Maths operators - java

I have this method which will generate a random maths expression solve it and output the answer to a variable:
public int Nov2()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
int novnum1 = rand.nextInt(101-1) + 1;
int novnum2 = rand.nextInt(101-1) + 1;
int nov2result = 0;
switch(op1) {
case '+': nov2result = novnum1 + novnum2; break;
case '-': nov2result = novnum1 - novnum2; break;
case '*': nov2result = novnum1 * novnum2; break;
case '/': nov2result = novnum1 / novnum2; break;
}
String nov2Exp = novnum1 + " " + op1 + " " + novnum2 + " = ";
Nov2resstor = nov2result;
setContentView(R.layout.gameview);
TextView display = (TextView) findViewById(R.id.exp);
display.setText(nov2Exp);
return nov2result;
}
How would i use the same sort of thing for expressions with more than two terms without having to write really complex if statements like this in my next method:
public int Eas3()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
i = rand.nextInt(4-0) + 0;
char op2 = ops[i];
int easnum1 = rand.nextInt(101-1) + 1;
int easnum2 = rand.nextInt(101-1) + 1;
int easnum3 = rand.nextInt(101-1) + 1;
int eas3result = 0;
if (op1 == '+' && op2 == '+')
{
eas3result = ((easnum1 + easnum2) + easnum3);
}
else if (op1 == '+' && op2 == '-')
{
eas3result = ((easnum1 + easnum2) - easnum3);
}
else if (op1 == '+' && op2 == '*')
{
eas3result = ((easnum1 + easnum2) * easnum3);
}
else if (op1 == '+' && op2 == '-')
{
eas3result = ((easnum1 + easnum2) - easnum3);
}
.../
I have methods which do this for 2,3,4,5 and 6 so my if statements would become very large using this method.
Any ideas?

you can use the built-in Javascript engine.
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Test
{
public static void main(String[] args) throws Exception
{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}

Yes, another way to do it is to write Command objects:
public interface Command<V> {
V execute(Object ... args);
}
You'll write an object that implements this interface:
public class AdditionCommand implements Command<Double> {
public Double execute(Object ... args) {
Double x = (Double)args[0];
Double y = (Double)args[1];
return x+y;
}
}
Now you can look up in a Map using the operator:
Map<String, Command> opsLookup = new HashMap<String, Command>() {{
opsLookup.put("+", new AddCommand<Number>());
opsLookup.put("-", new SubtractCommand<Number>());
}};
No need for a switch.

Check out this MathEval class I found online It will evaluate a String that represents an equation for you.
mySolver = new MathEval();
double answer = mySolver.evaluate(equation);

What you're looking for is called the composite pattern. You define an abstract Expression base class and derive it.
The classes must implement an evaluate() method which returns the result.
One sub class will be the constant which return it's value, another one would be a binary expression like plus, minus, etc. The evaluate() method will add/subtract/etc the result of the evaluated sub-expressions.
You can then build arbitrary expressions out of other expressions and then evaluate it without using one if condition.

How about using recursion:
int num(int numberOfOperands, int current){
if(numberOfOperands<=0) return current;
switch(rand.nextInt(4)){
case 0: return num(numberOfOperands-1, current + (rand.nextInt(100)+1)); break;
case 1: return num(numberOfOperands-1, current - (rand.nextInt(100)+1)); break;
case 2: return num(numberOfOperands-1, current * (rand.nextInt(100)+1)); break;
case 3: return num(numberOfOperands-1, current / (rand.nextInt(100)+1)); break;
}
}
int num(int numberOfOperands) throws Exception{
if(numberOfOperands <=0)
throw new Exception("invalid number of operands: "+numberOfOperands);
return num(numberOfOperands, rand.nextInt(100)+1);
}
This would, of course, ignore precedence of operations.

You could make a string with the variables you are using like this:
String temp = "(" + easnum1 + op1 + easnum2 + ")" + op2 + easnum3;
after that you can use the ScriptEngineManager class to use javascript as the engine so you can use the eval method.
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval(temp);
this method does the calculations and returns the result.
Hope this helps.

I would use an array for the values easnum[], an array for the operands op[] and an array with intermediate values.
Something along the following lines
for(...)
{
if(op[i]=='+') easintermediat[i+1] = easintermediate[i] + easnum[i]
...
}

If you've got n operations on n+1 numbers, and you do the first one, then you're left with n-1 operations on n numbers. You can use this as the basis for a loop that will process any number of items easily.
int operate(int[] numbers, int[] operations) {
if (numbers.length < 1 || numbers.length != operations.length + 1) {
throw new IllegalArgumentException();
}
int result = numbers[0];
for (int i = 0; i < operations.length; ++i) {
result = operate(operations[i], result, numbers[i+1]);
// where operate() is your switch statement
}
return result;
}

Try this:
public int Eas3()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
i = rand.nextInt(4-0) + 0;
char op2 = ops[i];
int easnum1 = rand.nextInt(101-1) + 1;
int easnum2 = rand.nextInt(101-1) + 1;
int easnum3 = rand.nextInt(101-1) + 1;
int eas3result = 0;
if (op1 == '+')
{
switch(op2)
{
case '+': eas3result=((easnum1 + easnum2) + easnum3); break;
case '-': eas3result=((easnum1 - easnum2) - easnum3); break;
case '*': eas3result=((easnum1 * easnum2) * easnum3); break;
case '/': eas3result=((easnum1 / easnum2) / easnum3); break;
}
}
..../
}
or even you can put outer IF in SWITCH like the following
public int Eas3()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
i = rand.nextInt(4-0) + 0;
char op2 = ops[i];
int easnum1 = rand.nextInt(101-1) + 1;
int easnum2 = rand.nextInt(101-1) + 1;
int easnum3 = rand.nextInt(101-1) + 1;
int eas3result = 0;
int tempResult=0;
switch(op1)
{
case '+': tempResult=(easnum1 + easnum2); break;
case '-': tempResult=(easnum1 + easnum2) ; break;
case '*': tempResult=(easnum1 + easnum2) ; break;
case '/': tempResult=(easnum1 + easnum2) ; break;
}
switch(op2)
{
case '+': eas3result=(tempResult + easnum3); break;
case '-': eas3result=(tempResult - easnum3); break;
case '*': eas3result=(tempResult * easnum3); break;
case '/': eas3result=(tempResult / easnum3); break;
}
}

Related

Java booth algorithm Shift or addition trouble

I just need a little help programming booths algorithm into java, I'm really not sure how to fix somethings, right now adding the right shift makes the entire answer 1(will show a few examples of inputs and outputs to explain and show) I know its converting to binary properly so I think my problem is in my shift and adding function.
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
System.out.print("Enter the first number: ");
int operand1 = sc.nextInt();
System.out.print("Enter the second number: ");
int operand2 = sc.nextInt();
String answer = multiply(operand1, operand2);
System.out.println(answer);
}
static String appendZeros(int n){
String result = "";
for(int i = 0; i < n; i++) result += "0";
return result;
}
public static String toBinary(int x, int len)
{
if (len > 0)
{
return String.format("%" + len + "s",
Integer.toBinaryString(x)).replaceAll(" ", "0");
}
return null;
}
static String add(String a, String b){
String result = "";
char carry = '0';
for(int i = a.length()-1; i >= 0; i--){
String condition = "" + a.charAt(i) + b.charAt(i) + carry;
switch(condition){
case "000": result = "0" + result; break;
case "001": result = "1" + result; carry = '0'; break;
case "010": result = "1" + result; break;
case "011": result = "0" + result; break;
case "100": result = "1" + result; break;
case "101": result = "0" + result; break;
case "110": result = "0" + result; carry = '1'; break;
case "111": result = "1" + result; break;
}
}
return result;
}
static String rightShift(String str){
String result = "";
for(int i = 0; i < str.length(); i++){
if(i == 0) result += str.charAt(i);
else result += str.charAt(i-1);
}
return result;
}
static String multiply(int a, int b){
String op1 = toBinary(a, 8);
String op2 = toBinary(b, 8);
String negop2 = toBinary(-b, 8);
if (op1.length() > 8)
{
op1 = op1.substring(op1.length() - 8);
}
if (op2.length() > 8)
{
op2 = op2.substring(op2.length() - 8);
}
if (negop2.length() > 8)
{
negop2 = negop2.substring(negop2.length() - 8);
}
System.out.println(op1 + " " + op2 + " " + negop2);
char prev = '0';
String product = appendZeros(16-op1.length())+op1;
for(int i = 0; i < 8; i++){
if(i > 0) prev = product.charAt(15);
if(product.charAt(15)=='0' && prev == '1'){
String temp = appendZeros(8-op2.length()) + op2 + appendZeros(8);
product = add(product, temp);
}
if(product.charAt(15)=='1' && prev == '0'){
String temp = appendZeros(8-negop2.length()) + negop2 + appendZeros(8);
product = add(product, temp);
}
product=rightShift(product);
}
return product;
}
input 9 1 output 1111111111111111 expected 0000000000001001 input 9 9
output 1111111111110111 expected 0000000001010001
I figured out my problem, the prev variable was being called too late so it didn't update the function properly, the prev value needed to be updated before the shift occurred. I moved it to right before the shift function was called and removed the if statement and it fixed it, it works perfectly now.
for(int i = 0; i < 8; i++){
//System.out.println("Did it change back?" + product.charAt(15) + prev);
//System.out.println("i = " + i);
if(product.charAt(15)=='0' && prev == '1'){
String temp = appendZeros(8-op2.length()) + op2 + appendZeros(8);
System.out.println(temp);
product = add(product, temp);
System.out.println("Add " + product);
}
if(product.charAt(15)=='1' && prev == '0'){
String temp = appendZeros(8-negop2.length()) + negop2 + appendZeros(8);
System.out.println(temp);
product = add(product, temp);
System.out.println("Subtract " + product);
}
prev = product.charAt(15);
product=rightShift(product);
System.out.println("Shift " + product);

RPN calculator with additional functions

I want to make the code use the stack class (stack of integers), together with a driver program which can handle the operations: 'm' unary minus -- negate the top item, 'r' exchange the top two items, 'd' duplicate top item on the stack, 'p' print (to the screen) the top item, n print and remove the top item, f print all the contents of the stack (leaving it intact), c clear the stack, 'q' quit, 'h' (or ?) print a help message.
import java.util.Scanner;
public class CalculatorDemo {
public static void main(String[] args)
{
String expression;
int result;
Scanner in = new Scanner(System.in);
do
{
calculator evaluator = new calculator();
System.out.println("Enter a valid post-fix expression one token " +
"at a time with a space between each token (e.g. 5 4 + 3 2 1 - + *)");
System.out.println("Each token must be an integer or an operator (+,-,*,/,%)for help(h/?)");
expression = in.nextLine();
result = evaluator.evaluate(expression);
System.out.println();
System.out.println(result);
}
while (result = 'q');
System.exit(0);
}
}
import java.util.*;
public class calculator
{
private Stack<Integer> stack;
public calculator()
{
stack = new Stack<Integer>();
}
public int evaluate(String expr)
{
int op1, op2, result = 0, help;
String key;
Scanner parser = new Scanner(expr);
while (parser.hasNext())
{
key = parser.next();
if (isOperator(key))
{
op2 = (stack.pop()).intValue();
op1 = (stack.pop()).intValue();
result = evaluateSingleOperator(key.charAt(0), op1, op2);
stack.push (new Integer(result));
}
else
stack.push(new Integer(Integer.parseInt(key)));
}
return result;
}
private boolean isOperator(String key)
{
return ( key.equals("+") || key.equals("-") ||
key.equals("*") || key.equals("/") ||
key.equals("h") || key.equals("?") ||
key.equals("p") || key.equals("n") ||
key.equals("d") || key.equals("r") ||
key.equals("c") || key.equals("f") ||
key.equals("%") || key.equals("m") ||
key.equals("q") );
}
private int evaluateSingleOperator(char operation, int op1, int op2)
{
int result = 0;
switch (operation)
{
case '+':
result = op1 + op2;
break;
case '-':
result = op1 - op2;
break;
case '*':
result = op1 * op2;
break;
case '/':
result = op1 / op2;
break;
case 'p':
result = op2;
break;
case '%':
result = op1 % op2;
break;
case 'm':
result = --op1;
break;
case'q':
result = (0);
break;
case'h'|'?':
int help = 0;
result = help;
break;
case 'r':
result = op1 ;//help
break;
case 'd':
result = op1;//help
break;
case 'n':
result = op1;//help
break;
case 'f':
result = op1;//help
break;
case 'c':
result = op1;//help
break;
}
return result;
}
private void help(String string) {
// TODO Auto-generated method stub
System.out.println("+ add the top two items" +
"* multiply the top two items" +
"- subtract the top item from the next item" +
"/ integer divide the second item by the top item" +
"% find the integer remainder when dividing the second item by the top item" +
"m unary minus -- negate the top item" +
"r exchange the top two items" +
"d duplicate top item on stack" +
"p print (to the screen) the top item" +
"n print and remove the top item" +
"f print all the contents of the stack (leaving it intact)" +
"c clear the stack" +
"q quit" +
"h (or ?) print a help message");
}
}

calculating sin, cos, log using stack and post fix notation in java

I wanna write a program that that take a infix string and change it to postfix then evaluate postfix and print the answer ; for +-*/^ it's easy just need precedence of operators but I don't know what should I do for sin cos log and other math function.
private static String infixToPostfix(String infix) {
String[] exp = infix.split("");
Stack<String> stack = new Stack<>();
String result = "";
for (int i = 0; i < exp.length; i++){
if (exp[i].equals("(")) {
stack.push(exp[i]);
}
else if (isOperator(exp[i]))
{
while (!stack.isEmpty() && precedence(exp[i]) <= precedence(stack.getTop())){
result += stack.pop() + " ";
}
stack.push(exp[i]);
}
else if (exp[i].equals(")"))
{
while (!stack.isEmpty() && !stack.getTop().equals("(")){
result += stack.pop() + " ";
}
stack.pop();
}
else if (Character.isLetterOrDigit(infix.charAt(i)) || exp[i].equals(".")){
boolean haveDot = exp[i].equals(".");
String temp = haveDot ? "0." : exp[i];
while ((i + 1) < exp.length && (Character.isLetterOrDigit(infix.charAt(i + 1)) || exp[i + 1].equals("."))){
temp += exp[i + 1];
i++;
}
result += temp + " ";
}
}
while (!stack.isEmpty()){
result += stack.pop() + " ";
}
return result;
}
it is working correctley !
but this
private static Double postFixEvaluator(String[] postFix) {
Stack<Double> operands = new Stack<>();
double value = 0.0;
for (int str = 0; str < postFix.length; str++) {
if (postFix[str].trim().equals("")) {
continue;
}
switch (postFix[str]) {
case "+":
case "-":
case "*":
case "/":
case "^":
Double right = operands.pop();
Double left = operands.pop();
long intValue = 0;
switch (postFix[str]) {
case "+":
value = left + right;
break;
case "-":
value = left - right;
break;
case "*":
value = left * right;
break;
case "/":
value = left / right;
break;
case "^":
value = Math.pow(left, right);
break;
default:
break;
}
case "sin":
case "cos":
case "tan":
case "cot":
if (Character.isLetterOrDigit(Arrays.toString(postFix).charAt(str + 2))) {
str++;
break;
}
else{
Double oper = operands.pop();
switch (postFix[str]) {
case "sin":
value = Math.sin(oper);
break;
case "cos":
value = Math.cos(oper);
break;
case "tan":
value = Math.tan(oper);
break;
case "cot":
value = 1 / Math.tan(oper);
break;
}
}
operands.push(value);
break;
default:
operands.push(Double.parseDouble(postFix[str]));
break;
}
}
return operands.pop();
}
it's not working correctly .

Calculator using Switch in Java

I'm new to Java programming. I am trying to make a Fraction Calculator but when I try to run the program it gives me an error. The error is with the Switch statements but I don't know what happened.
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.println("Welcome to My FracCalc");
boolean continueProcessing = true;
while (continueProcessing) {
System.out.println("Type an expression and press <enter>");
String Operand1 = console.next();
if (Operand1.equals("quit")) {
continueProcessing = false;
System.out.println("Good bye!");
break;
} else {
Operand1 = parseFullNumber(Operand1);
}
String Operator = console.next();
if (Operator.equals("quit")) {
continueProcessing = false;
System.out.println("Good bye!");
break;
} else if (Operator.equals("+") || Operator.equals("-") || Operator.equals("/") || Operator.equals("*")) {
} else {
throw new ArithmeticException();
}
String Operand2 = console.next();
if (Operand2.equals("quit")) {
continueProcessing = false;
System.out.println("Good bye!");
break;
} else {
Operand2 = parseFullNumber(Operand2);
}
System.out.println( Operand1 + " " + Operator + " " + Operand2);
//System.out.println("First Fraction is: " + Operand1);
//System.out.println("Operator is: " + Operator);
//System.out.println("Second Fraction is: " + Operand2);
float answer;
System.out.println(Operator);
switch (Operator) {
case "+":
answer = Operand1 + Operand2;
break;
case "-":
answer = Operand1 - Operand2;
break;
case "*":
answer = Operand1 * Operand2;
break;
case "/":
answer = Operand1 / Operand2;
break;
}
}
}
public static String parseFullNumber(String input) {
int wholeNumber = 0;
int numerator = 0;
int denominator = 0;
;
int underscoreId = input.indexOf('_');
int slashId = input.indexOf('/');
// Check for underscore "_" //
if (underscoreId > -1) {
wholeNumber = Integer.parseInt(input.substring(0, underscoreId));
numerator = Integer.parseInt(input.substring(underscoreId + 1, slashId));
denominator = Integer.parseInt(input.substring(slashId + 1, input.length()));
} else {
if (slashId > -1) {
// no underscore but there is a slash //
numerator = Integer.parseInt(input.substring(0, slashId));
denominator = Integer.parseInt(input.substring(slashId + 1, input.length()));
} else {
// there is no underscore or slash //
wholeNumber = Integer.parseInt(input);
}
}
return simplify(wholeNumber, numerator, denominator);
}
//simplifying fractions //
public static String simplify(int wholeNumber, int numerator, int denominator) {
// absolute values //
int absNumerator = Math.abs(numerator);
// factor if applicable //
if (absNumerator > 1) {
int commonFactor = 1;
for (int i = 2; i < Math.min(absNumerator, denominator); i++) {
if (numerator % i == 0 && denominator % i == 0) {
commonFactor = i;
}
}
numerator /= commonFactor;
denominator /= commonFactor;
}
// reduce if applicable //
if (absNumerator > denominator) {
int reduction = numerator / denominator;
if (wholeNumber >= 0) {
wholeNumber += reduction;
} else {
wholeNumber -= reduction;
}
numerator %= denominator;
}
// prints //
if (wholeNumber != 0) {
if (numerator != 0) {
return wholeNumber + "_" + numerator + "/" + denominator;
} else {
return String.valueOf(wholeNumber);
}
} else {
if (numerator != 0) {
return numerator + "/" + denominator;
} else {
return String.valueOf(0);
}
}
}
}
Here is the error i got:
Exception in thread "main" java.lang.Error:
Unresolved compilation problems:
Type mismatch:
cannot convert from String to float The operator - is undefined for the argument type(s) java.lang.String, java.lang.String
The operator * is undefined for the argument type(s) java.lang.String, java.lang.String
The operator / is undefined for the argument type(s) java.lang.String, java.lang.String
at FracCalcApp.main(FracCalcApp.java:53)
Operand1 and Operand2 are String(s). You need to parse them before you can perform arithmetic. Something like,
double answer;
System.out.println(Operator);
switch (Operator) {
case "+":
answer = Double.valueOf(Operand1) + Double.valueOf(Operand2);
break;
case "-":
answer = Double.valueOf(Operand1) - Double.valueOf(Operand2);
break;
case "*":
answer = Double.valueOf(Operand1) * Double.valueOf(Operand2);
break;
case "/":
answer = Double.valueOf(Operand1) / Double.valueOf(Operand2);
break;
}
Finally, by convention, Java variables should start with a lower case letter; operand1, operand2 and operator.
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("Enter first number");
float a = sc.nextFloat();
System.out.println("Enter second number");
float b = sc.nextFloat();
System.out.println("choose your operation");
char operator = sc.next().charAt(0);
float answer;
switch (operator){
case '+' :
answer = a +b;
System.out.println("Answer:"+answer);
break;
case '-' :
answer = a-b;
System.out.println("Answer:"+answer);
break;
case '*' :
answer = a*b;
System.out.println("Answer:"+answer);
break;
default:
answer = a/b;
System.out.println("Answer:"+answer);
}
}

Converting infix expressions to postfix expressions

I have a problem i can't find the wrong in this function it sometimes do well with any input but it cached when there is parentheses in the input {i want to know where is the wrong in this code and how to fix it , and Is there another better way instead this way}
public static String Converting_infix_expressions_to_postfix_expressions(String infix) throws Exception{
StringTokenizer st = new StringTokenizer(infix);
int numOF_tokens = st.countTokens();
String postfix = "" ;
for (int i = 1; i <= numOF_tokens; i++) {
String term = st.nextToken();
try { // if it is an Float there is no problem will happen
float x = Float.parseFloat(term);
postfix += x +" " ;
System.out.println("term is number " + term);
} catch (Exception e) {
System.out.println("term is symbol " + term);
if(stack.isEmpty())
stack.push(term);
else if(term == "(")
stack.push(term);
else if(term == ")"){
while((String)stack.peek() != "(")
postfix += stack.pop() +" ";
stack.pop();
}
else{
int x = 0,y = 0;
switch(term){
case "+": x = 1; break;
case "-": x = 1; break;
case "*": x = 2; break;
case "/": x = 2; break;
}
switch((String)stack.peek()){
case "+": y = 1; break;
case "-": y = 1; break;
case "*": y = 2; break;
case "/": y = 2; break;
}
if(x > y)
stack.push(term);
else {
int x1 = x , y1 = y;
boolean puchedBefore = false;
while(x1 <= y1){
postfix += stack.pop() +" ";
if(stack.isEmpty() || stack.peek() == "(" ){
stack.push(term);
puchedBefore = true;
break;
}
else{
switch(term){
case "+": x1 = 1; break;
case "-": x1 = 1; break;
case "*": x1 = 2; break;
case "/": x1 = 2; break;
}
switch((String)stack.peek()){
case "+": y1 = 1; break;
case "-": y1 = 1; break;
case "*": y1 = 2; break;
case "/": y1 = 2; break;
}
}
}
if(!puchedBefore)
stack.push(term);
}
}
}
}
while(!stack.isEmpty()){
postfix += stack.pop() +" ";
}
System.out.println("The postfix expression is : " + postfix);
return postfix;
}
You have a couple of problems with your code.
You should make a custom string tokenizer since there may not be a space between a parenthesis and a number. Ex: (5 + 6)
The try-catch block is not being used properly. Consider, first checking if the field is symbol then moving on to parsing it as a Float. This way you can avoid having most of your code appear in the catch block.
The bug you are referring to can be fixed with the follow change to line 18.
while(!stack.isEmpty() && (String)stack.peek() != "(")

Categories