I am trying to write calculator for + - * / without conditions. The operator is stored as a string.
Is there anyway to achieve it?
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
////String Operator = "";
String L1="";
String L2="";
String op = "+";
double a = 3;
double b = 2;
//Operator p = p.
Operator p;
b = Operator.count(a, op, b);
System.out.println(b);
}
public enum Operator {
PLUS("+"), MINUS("-"), DIVIDE("/"), MULTIPLY("*");
private final String operator;
public static double count(double a,String op,double b) {
double RetVal =0;
switch (Operator.valueOf(op)) {
case PLUS:
RetVal= a + b;
case MINUS:
RetVal= a - b;
case DIVIDE:
RetVal= a / b;
case MULTIPLY:
RetVal= a * b;
}
return RetVal;
}
Operator(String operator) {
this.operator = operator;
}
// uniwersalna stała grawitacyjna (m3 kg-1 s-2)
}
}
Got this error:
Exception in thread "main" java.lang.IllegalArgumentException: No enum const class Main$Operator.+
Any clues?
You could use a strategy pattern and store a calculation strategy for each operator.
interface Calculation {
double calculate(double op1, double op2);
}
class AddCalculation implements Calculation {
double calculate(double op1, double op2) {
return op1 + op2;
}
}
//others as well
Map<String, Calculation> m = ...;
m.put("+", new AddCalculation());
During execution you then get the calculation objects from the map and execute calculate().
i think using an enum would be a nice option:
Enum Operation{
PLUS("+")
MINUS("-")
DIVIDE("/")
MULTIPLY("*")
}
then you could go with
switch(Operation.valueOf(userInputString)){
case PLUS: return a+b;
case MINUS: return a-b;
case DIVIDE: return a/b;
case MULTIPLY: return a*b;
}
how about hashing? Hash the operators as a key-value pair ("+": +). For the string operatory, hash it and grab the value. Experiment with that
As mentioned by Peter Lawrey, ScriptEngine/JavaScript might be a good choice for this. Visit this little JavaScript interpreter applet to explore the possibilities.
Related
I'm trying to find the index of a char that splits two numbers, the char can either be +, -, / or *. I'm making a simple calculator.
The process would be extremely trivial if i could use the indexofAny method, because i would be able to check for all 4 values in 1 line. Sadly, it's not available in Java.
NOTE: I do not want to use indexOf, since i would have to write 4 lines of nearly identical code.
My main class:
import java.util.Scanner;
public class Main {
static Scanner scanner = new Scanner(System.in);
public static MathUserInput readInput() {
String input = scanner.nextLine();
String[] parts = input.split("\\+|-|/|\\*");
int firstNumber = Integer.parseInt(parts[0]);
int secondNumber = Integer.parseInt(parts[1]);
char operation = input.charAt(1);
return new MathUserInput(firstNumber, secondNumber, operation);
}
public static void main(String[] args) {
System.out.println("This is a calculator.");
System.out.println();
System.out.println("Please provider a number, an operator and a number");
System.out.println();
MathUserInput input = readInput();
char operation = input.getOperation();
switch (operation) {
case '+':
System.out.println(input.getFirstNumber() + input.getSecondNumber());
break;
case '-':
System.out.println(input.getFirstNumber() - input.getSecondNumber());
break;
case '*':
System.out.println(input.getFirstNumber() * input.getSecondNumber());
break;
case '/':
System.out.println(input.getFirstNumber() / input.getSecondNumber());
break;
}
}
}
I'm currently using a switch statement, but i'm hoping that there's a better alternative. Essentially, i'm aiming to only have 1 line that outputs the result in the calculator.
Thank you!
You can use StringUtils#indexOfAny(CharSequence, char...) from Apache Commons Lang which does exactly what you want.
import org.apache.commons.lang3.StringUtils;
public static MathUserInput readInput() {
String input = scanner.nextLine();
int pos = StringUtils.indexOfAny(input, '+', '-', '/', '*');
return new MathUserInput(input.substring(0, pos), input.substring(pos + 1), input.charAt(pos));
}
If you don't want to include a library for this, you can always write your own utility. Have a look at the code of StringUtils to be inspired. They are basically looping over the characters of the input string and in a nested loop over the characters to be found. The index of the first match is then returned.
I think you can use enum for the operations and encapsulate logic in it:
public class Main {
public static void main(String... args) {
Scanner scan = new Scanner(System.in);
scan.useLocale(Locale.ENGLISH);
System.out.println("This is a calculator.");
System.out.println("Please provider a number, an operator and a number");
MathUserInput input = readInput(scan);
System.out.println(input.execute());
}
private static final Pattern PATTERN = Pattern.compile("(?<a>[^+\\-*\\/]+)(?<operation>[+\\-*\\/]+)(?<b>[^+\\-*\\/]+)");
private static MathUserInput readInput(Scanner scan) {
Matcher matcher = PATTERN.matcher(scan.nextLine());
if (!matcher.matches())
throw new RuntimeException("Incorrect expression");
double a = Double.parseDouble(matcher.group("a").trim());
double b = Double.parseDouble(matcher.group("b").trim());
Operation operation = Operation.parseSign(matcher.group("operation").trim().charAt(0));
return new MathUserInput(a, b, operation);
}
private static final class MathUserInput {
private final double a;
private final double b;
private final Operation operation;
public MathUserInput(double a, double b, Operation operation) {
this.a = a;
this.b = b;
this.operation = operation;
}
public double execute() {
return operation.execute(a, b);
}
}
private enum Operation {
SUM('+', Double::sum),
SUBTRACTION('-', (a, b) -> a - b),
MULTIPLY('*', (a, b) -> a * b),
DIVISION('/', (a, b) -> a / b);
private final char sign;
private final BiFunction<Double, Double, Double> func;
Operation(char sign, BiFunction<Double, Double, Double> func) {
this.sign = sign;
this.func = func;
}
public final double execute(double a, double b) {
return func.apply(a, b);
}
public static Operation parseSign(char sign) {
for (Operation operation : values())
if (operation.sign == sign)
return operation;
throw new EnumConstantNotPresentException(Operation.class, Character.toString(sign));
}
}
}
I am creating a Calculator with + - * / and %(Modulus). The basic calculator is working but I am now wondering how I should prioritise multiplication and division before addition and substraction. Can't really figure it out.
I need to write a whole string which will be converted to a double and then back to string for printout.
example: 3+3-4*8+5/6+5
Here is my code below
public String calculateExpression(String expression){
double dres = 0.0;
String[] split = expression.split("(?=[*/+-])|(?<=[*/+-])");
dres = Double.parseDouble(split[0]);
for (int i = 1; i < split.length; i+= 2) {
String op = split[i];
double val = Double.parseDouble(split[i+1]);
switch (op) {
case "+":
dres = Addition(dres, val);
break;
case "-":
dres = Subtraction(dres, val);
break;
case "*":
dres = Multiplication(dres, val);
break;
case "/":
dres = Division(dres, val);
break;
default:
break;
}
}
String res = Double.toString(dres);
return res;
}
public double Addition(double d1,double d2) {
return d1+d2;
}
public double Subtraction(double d1, double d2) {
return d1-d2;
}
public double Multiplication(double d1, double d2) {
return d1*d2;
}
public double Division(double d1, double d2) {
return d1/d2;
}
public double Modulus(double d1, double d2) {
return d1%d2;
}
What you can do is scan for the right-most occurrence of a * or /, and split the String into two parts (to the left of the symbol and to the right of the symbol). Then, call your own method to determine the values of either side; then perform the multiplication/division operation.
If there isn't any * or /, you can do the same thing for + and -.
If there isn't any operator at all, then just return the number.
Maybe try something like a brute force approach:
public String calculateExpression(String expression){
double dres = 0.0;
String[] split = expression.split("(?=[*/+-])|(?<=[*/+-])");
dres = Double.parseDouble(split[0]);
for (int i = 1; i < split.length; i+= 2) {
String op = split[i];
double val = Double.parseDouble(split[i+1]);
switch (op) {
if(case == "+" or case == "*") {
case "+":
dres = Addition(dres, val);
break;
case "*":
dres = Multiplication(dres, val);
break;
}
else {
case "-":
dres = Subtraction(dres, val);
break;
case "/":
dres = Division(dres, val);
break;
}
default:
break;
}
}
String res = Double.toString(dres);
return res; }
Not sure if the code is correct, but you get the gist.
This is a classic application of the Interpreter Pattern.
Unfortunately, I had trouble understanding what exactly the example on wikipedia is doing...
But the solution definitely has to do with stacks (called ArrayDeque in Java).
I am a java student and I am working to make my code more object oriented. I can easily code calculator in main but I'm really struggling to implement it with methods. The following code will always return 0...but the goal is to create a program which allows a user to enter an operator and a number in one line (example +5) the code should output the previous value, the new value, and allow for resetting. I believe I am really close to solving this and just need a point in the right direction..
output
Enter an operator and a number:
+5
0.0
Calculator class
import java.util.Scanner;
public class Calculator {
private final int RESET = 0;
private double number = 0;
private double result = 0; // I believe this is the issue but how can I resolve it?
private char operator;
private static Scanner keyboard = new Scanner(System.in);
public Calculator(double number)
{
this.number = number;
}
// this method invokes the whatOperator() to create a new result
// the edited method still returns 0
public double aResult(Calculator other)
{
other.whatOperator();
this.result = other.result;
return result;
}
// I created this method in hopes that it would do most of the work..when I invoke it and enter my operator and number it does not seem to function correctly
public void whatOperator()
{
String operator = null;
operator = enterNumber();
double theNumber = Double.parseDouble(operator);
char theOperator =operator.charAt(0);
operator = null;
operator += theOperator;
// switch method to find the operator
switch(operator){
case "*":
result = getNumber() * theNumber;
break;
case "/":
result = getNumber() / theNumber;
break;
case "+":
result = getNumber() + theNumber;
break;
case "-":
result = getNumber() - theNumber;
break;
case "R":
result = RESET;
break;
}
}
// methods for operation...I was hoping to not use these
public double add(double secondNumber)
{
result = number + secondNumber;
return result;
}
public double divide(double secondNumber)
{
result = number / secondNumber;
return result;
}
public double multiply(double secondNumber)
{
result = number * secondNumber;
return result;
}
public void subtract(double secondNumber)
{
result = number - secondNumber;
}
public double getNumber()
{
return number;
}
// method for getting input
public static String enterNumber()
{
System.out.println("Enter an operator and a number:");
String toString = keyboard.nextLine();
return toString;
}
public static void main (String[] args) {
// the calculator is initialized at 0
Calculator a = new Calculator(0);
// now I create a second calculator with the result from the aResult()
Calculator b = new Calculator(a.aResult(a));
// why is b.getNumber() = 0 at this point?
String theString = String.valueOf(b.getNumber());
// prints 0 every time
System.out.println(theString);
}
}
There are some mistakes in your code.
public double aResult(Calculator other)
{
other = new Calculator(getNumber());
other.whatOperator();
this.result = result;
return result;
}
The line this.result = result doesn't make any sense. I think you wanted the method whatOperator() to return a result e.g.
this.result = other.whatOperator();
I also think that you don't want to override the "other" calculator. You never use the new calculator. But you want to print the output of the new calculator in your main method. Because you never used the new calculator, the output is 0.
In your aResult method you are initiating another new instance of Calculator
public double aResult(Calculator other) {
//other = new Calculator(getNumber()); // this should not be here
other.whatOperator();
this.result = result;
return result;
}
The solution to the problem:
//change
this.result = result; //this does nothing
//to
this.result = other.result; //this changes the result to the new value
//erase this line
other = new Calculator(getNumber()); // do not need to create a new calculator
change the method whatOperator to a double and return a double with it
public class ArithmeticTester {
public static void main(String[] args) {
call(3, "+", 4, "7");
call(3, "-", 4, "-1");
call(3, "*", 4, "12");
call(3, "#", 4, "java.lang.IllegalArgumentException");
call(13, "/", 4, "3");
call(13, "/", 0, "java.lang.IllegalArgumentException");
}
public static void call(int a, String op, int b, String expected) {
try {
System.out.println(Arithmetic.compute(a, op, b));
} catch (Throwable ex) {
System.out.println(ex.getClass().getName());
}
System.out.println("Expected: " + expected);
}
}
This is provided by the book as the testing class
public class Arithmetic
{
/**
Computes the value of an arithmetic expression
#param value1 the first operand
#param operator a string that should contain an operator + - * or /
#param value2 the second operand
#return the result of the operation
*/
public static int compute(int value1, String operator, int value2)
{
int a;
a = 1;
String b;
b = "-";
int c;
c = 3;
return (a, b, c);
}
}
I dont even really know where to begin, i am completely lost at what to even do the book does a bad job of explaining what to do and my teacher is useless at helping students.
Am i supposed to make an if statement that changes operator ever time it loops? Please help.
Edit: Prompt
Write a method that computes the value of an arithmetic expression.
The operator string should be one of ("+", "-", "*", or "/").
The method should throw an IllegalArgumentException otherwise.
Also throw an IllegalArgumentException if the operator is "/"
and the second argument is zero.
*/
Implement Arithmetic.compute(int, String, int), something like1
public static int compute(int value1, String operator, int value2) {
if ("+".equals(operator)) {
return value1 + value2;
} else if ("-".equals(operator)) {
return value1 - value2;
} else if ("*".equals(operator)) {
return value1 * value2;
} else if ("/".equals(operator)) {
if (value2 != 0) {
return value1 / value2;
}
throw new IllegalArgumentException("Division By 0");
}
throw new IllegalArgumentException(String.format("Unknown operator (%s)",
operator));
}
then run ArithmeticTester and you will see that the rest of your code invokes the compute function and outputs diagnostic messages indicating test pass/failure conditions. The above implementation passes the provided tests.
1Using Yoda conditions.
You would need a function that does something like this...
public static int compute(int val1, int val2, String op) {
// +
if (op.equals("+"))
return val1 + val2;
// -
else if (op.equals("-"))
return val1 - val2;
// *
else if (op.equals("*"))
return val1 * val2;
// /
else if (op.equals("/")) {
if(val2 == 0)
throw new IllegalArgumentException("Can't divide by 0");
return (int)(val1 / val2);
}
else
throw new IllegalArgumentException("Op not supported");
}
Let me know if something is not clear.
I'm working on a java object oriented expression tree assignment where I need to be able to eval and print expression trees in prefix/infix/postfix formats. The assignment describes a class hierarchy with static type "Exp" and several unary and binary subclasses.
I've solved the eval part by having the unary and binary classes implement the eval() method (as dictated by the root type "Exp"), but need help with printing the expression. I've worked with this for days now and have gotten nowhere. All the help I've found online is about binary classes that has both operator and values fields (my assignment has these as two different classes). Please give me a kick in the right direction - I'll be most grateful :-)
Best wishes,
Rasmus
public interface Exp { double value(); }
public class Value implements Exp {
private double value;
public Value(double val) { this.value = val; }
public double value() { return this.value; }
}
public class Binary implements Exp {
private char op; private Exp right; private Exp left;
public Binary(char op, Exp left, Exp right) {
this.op = op; this.left = left; this.right = right;
}
}
public double value() { // sum up using recursion
switch(this.op) {
case '+': return this.left.value()+this.right.value();
case '-': return this.left.value()-this.right.value();
case '*': return this.left.value()*this.right.value();
case '/': return this.left.value()/this.right.value();
default: return Double.NaN;
}
}
}
public class Main { //calculating total ok - needs printing!
public static void Main(String[] args) {
Exp valLeft = new Value(10);
Exp valRight = new Value(5);
Exp bN1 = new Binary('+', valLeft, valRight);
Exp bN2 = new Binary('+', bN1, new Value(3));
System.out.println(bN2.value());
}
}
Here's how to do the infix. The prefix and postfix should be possible for you once you see how this one is done.
In the Exp interface, add:
String asInfix();
In the Binary class, add:
public final String asInfix() {
return "(" + left.asInfix() + " " + op + " " + right.asInfix() + ")";
}
In the Value class, add:
public final String asInfix() {
return "" + value;
}
Now you can do System.out.println(bN2.asInfix()); to display ((10.0 + 5.0) + 3.0).
Approach it in same manner. Override toString so that it calls it recursively for left and right in case of Binary, and returns the value for Value nodes.