RPN calculator with additional functions - java

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");
}
}

Related

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 .

'Error: Expected' when creating switch

import java.util.Scanner;
public class lab05a
{
public static void main (String[] args)
{
String statement;
Scanner scan = new Scanner(System.in);
int vowela;
int vowele;
int voweli;
int vowelo;
int vowelu;
int nonvowel;
int vowela = 0;
int vowele = 0;
int voweli = 0;
int vowelo = 0;
int vowelu = 0;
statement = scan.nextString();
statement = statement.toLowerCase();
for (int i = 0; i <= statement.length(); count++)
{
char c = examplestring.charAt(i);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
switch (c)
{
case 'a':
vowela += 1;
break;
case 'e':
vowele += 1;
break;
case 'i';
voweli += 1;
break;
case 'o';
vowelo += 1;
break;
case 'u';
vowelu += 1;
break;
}
else
nonvowel +=1;
}
System.out.prinln("a: " + vowela);
System.out.prinln("e: " + vowele);
System.out.prinln("i: " + voweli);
System.out.prinln("o: " + vowelo);
System.out.prinln("u: " + vowelu);
System.out.prinln("nonvowel: " + novowel);
}
}
I thought of doing it this way:
First I create a for loop to iterate through every character of String statement.
Then I put an if statement in the for loop that checks if c(declared as statement.charAt(i)) is a vowel.
If c is a vowel I use a switch to increase the count for that particular vowel by one and then break.
If c is not a vowel, it gets added to the count of consonants.
After the for loop is done it prints the count of each character.
The switch is where I am having problems. Case 'a' and case 'e' have cause no errors, but cases 'i' through 'u' cause an error('Error: : Expected').
I don't understand what this means or why, as cases 'i' through 'u' are written the same way as cases 'a' and 'e'. Can someone help me out?
3 errors found:
[line: 38] Error: : expected
[line: 41] Error: : expected
[line: 44] Error: : expected
Sorry if this post is poorly formatted I am new to Stack Overflow.
There are many errors in your code, I have modified it (posted at the bottom) and pointed out some of your mistakes:
Change statement = scan.nextString().toLowerCase(); to statement = scan.nextLine().toLowerCase();
I don't understand what this means or why, as cases 'i' through 'u' are written the same way as cases 'a' and 'e'.
Your switch is wrong because cases i, o, and u have a semi-colon(;) instead of a colon(:). Just that small difference is causing the error there. Change your switch statement to this:
switch(c) {
case 'a':
vowela++;
break;
case 'e':
vowele++
break;
case 'i':
voweli++
break;
case 'o':
vowelo++
break;
case 'u':
vowelu++;
break;
}
Here's your modified code. Now it is correct, and it works:
import java.util.Scanner;
public class lab05a {
public static void main (String[] args) {
String statement;
Scanner scan = new Scanner(System.in);
int vowela = 0;
int vowele = 0;
int voweli = 0;
int vowelo = 0;
int vowelu = 0;
int nonvowel = 0;
statement = scan.nextLine().toLowerCase();
for (int i = 0; i < statement.length(); i++) {
char c = statement.charAt(i);
switch (c) {
case 'a':
vowela++;
break;
case 'e':
vowele++;
break;
case 'i':
voweli++;
break;
case 'o':
vowelo++;
break;
case 'u':
vowelu++;
break;
default:
nonvowel++;
break;
}
}
System.out.println("a: " + vowela);
System.out.println("e: " + vowele);
System.out.println("i: " + voweli);
System.out.println("o: " + vowelo);
System.out.println("u: " + vowelu);
System.out.println("nonvowel: " + nonvowel);
}
}
You may have noticed some changes such as removing the if statement that checks for a vowel. Rather than doing all of that, I just added a default case. If none of the other conditions are true, than whatever is in the default case is executed. I also initialized your variables vowela, vowele, voweli, etc., and rather than doing vowela += 1 I just changed it to vowela++, which produces the same effect(same with the other letters).

RPN Calculator Using Stacks

This is some code I got from my textbook which is a calculator solving expressions entered as postfix notation. I was wondering if there was a way I could keep using the stack instead of the stack restarting once the program evaluates an expression.
import java.util.Scanner;
import java.util.Stack;
public class RPN2
{
private Stack<Integer> stack;
public RPN2()
{
stack = new Stack<Integer>(); //creates stack
}
public static void main(String[] args)
{
String expression, again;
int result;
Scanner keyboard = new Scanner(System.in);
do
{
RPN2 evaluator = new RPN2();
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 (+,-,*,/)");
expression = keyboard.nextLine();
result = evaluator.evaluate(expression);
System.out.println();
System.out.println("That expression equals " + result);
System.out.print("Evaluate another expression [Y/N]? ");
again = keyboard.nextLine();
System.out.println();
}
while (again.equalsIgnoreCase("y"));
}
public int evaluate(String expr)
{
int op1, op2, result = 0;
String token;
Scanner parser = new Scanner(expr);
while (parser.hasNext())
{
token = parser.next();
if (isOperator(token)) //if operator pop
{
op2 = (stack.pop()).intValue();
op1 = (stack.pop()).intValue();
result = evaluateSingleOperator(token.charAt(0), op1, op2); //
stack.push(new Integer(result));
}
else
stack.push(new Integer(Integer.parseInt(token)));
}
return result;
}
private boolean isOperator(String token)
{
return ( token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("/") || token.equals("%") );
}
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 '%':
result = op1 % op2;
break;
}
return result;
}
}
Yes you can, see comments :
public RPN2() {
stack = new Stack<>(); //creates stack
}
void clearStack(){ //add clear stach method
stack.clear();
}
public static void main(String[] args)
{
String expression, again;
int result;
Scanner keyboard = new Scanner(System.in);
RPN2 evaluator = new RPN2(); //move out of the do loop
do
{
evaluator.clearStack();//use clear stack method
//rest of the code omitted (no change in it)

Java display does not show whole method

Having trouble with this the whole day. Please help me. I can't get the problem to display
The output shows
PROBLEM NUMBER 1
Answer:0
Correct....
PROBLEM NUMBER 2
Answer:1
Wrong....
It must show:
PROBLEM NUMBER 1
10 + 11 = ?
Answer: 21
Correct...*/
import java.util.Random;
import java.util.*;
import java.util.Scanner;
import javax.swing.JOptionPane;
import java.lang.Math;
public class MathIsSuperFun1{
Scanner input = new Scanner(System.in);
int correctAnswers;
int randomNum1;
int randomNum2;
int choice;
int corrrectAnswers, wrongAnswers;
String playerName ="";
int operation;
int userAnswer;
int correctAnswer = 0;
int userRemainder, correctRemainder;
int x = 0;
int temporaryNum1, temporaryNum2;
int range;
int randomNumber;
public static void main (String args[]){
MathIsSuperFun1 lab = new MathIsSuperFun1();
lab.init();
}
public void init(){
getName();
pickDifficulty();
pickOperation();
for(int x = 0; x < 10; x++)
{
System.out.println("\t\t\t~~~~~~~PROBLEM NUMBER" + (x + 1) + "~~~~~~~~");
assignNum();
getProblem();
checkAnswer();
}
}
//GET PLAYER NAME USING PANE
public static String getName(){
String playerName;
playerName = JOptionPane.showInputDialog(null, "Welcome!\nEnter your name and press OK.", "Math Is Super Fun!", JOptionPane.QUESTION_MESSAGE);
System.out.println("Do your best," + playerName + "!");
return playerName;
}
//GET PROBLEM BASED ON OPERATION
public void getProblem(){
switch(operation){
case 1:
System.out.println(randomNum1 + "+" + randomNum2 + "= ?\n");
correctAnswer = randomNum1 + randomNum2;
break;
case 2:
System.out.println(randomNum1 + "-" + randomNum2 + "= ?\n");
correctAnswer = randomNum1-randomNum2;
break;
case 3:
System.out.println(randomNum1 + "*" + randomNum2 + "= ?\n");
correctAnswer = randomNum1*randomNum2;
break;
case 4:
System.out.println(randomNum1 + "/" + randomNum2 + "= ?\n");
correctAnswer = randomNum1/randomNum2;
correctRemainder = randomNum1%randomNum2;
break;
}
System.out.print("Answer: ");
userAnswer = input.nextInt();
if(operation == 4){
System.out.print("Remainder: ");
userRemainder = input.nextInt();
}
return 0;
}
//PICK DIFFICULTY USING DIALOG
public void pickDifficulty(){
int choice = 0;
System.out.println("1 - Child's Play\n2 - No Sweat\n3 - Bitter\n4 - Cold-blooded\n5 - Brutal\n6 - Genius");
choice = input.nextInt();
}
//PICK OPERATIONS
public void pickOperation(){
int operation = 0;
System.out.println("1 - Addition\n2 - Subtraction\n3 - Multiplication\n4 - Division ");
operation = input.nextInt();
}
//GET NUMBER RANGE BASED ON DIFFICULTY
public int numberRange(){
int range = 0;
switch(choice){
case 1:
range = 100;
break;
case 2:
range = 1000;
break;
case 3:
range = 10000;
break;
case 4:
range = 100000;
break;
case 5:
range = 1000000;
break;
case 6:
range = 10000000;
break;
}
return range;
}
//GET CORRECT RANDOM RESPONSE USING CASE SWITCH BASED ON GETRANDOM METHOD
public void correctResponse(){
String responseCorrect = "";
switch (getRandom(5)){
case 1:
responseCorrect = "Correct. Keep up the good work!";
break;
case 2:
responseCorrect = "Correct. Keep aiming higher!";
break;
case 3:
responseCorrect = "Correct. Well done!";
break;
case 4:
responseCorrect = "Correct. Nice work!";
break;
case 5:
responseCorrect = "Correct. We're almost there!";
break;
}
System.out.println(responseCorrect);
correctAnswers += 1;
}
//GET WRONG RANDOM RESPONSE USING CASE SWITCH BASED ON GETRANDOM METHOD
public String wrongResponse(){
String responseWrong = "";
switch (getRandom(5)){
case 1:
responseWrong = "Wrong. Don't give up!";
break;
case 2:
responseWrong = "Wrong. You can do it!";
break;
case 3:
responseWrong = "Wrong. Try again puny human!";
break;
case 4:
responseWrong = "Wrong. You must be really weak at math!";
break;
case 5:
responseWrong = "Wrong. I pity you!";
break;
}
System.out.println(responseWrong);
System.out.println("The correct answer is:" + correctAnswer);
if(operation == 4)
System.out.println("Correct Remainder: " + correctRemainder);
return responseWrong;
}
public void checkAnswer(){
if(operation != 4 && userAnswer == correctAnswer){
correctResponse();
}
else if(operation == 4 && userAnswer == correctAnswer && userRemainder == correctRemainder){
correctResponse();
}
else{
wrongResponse();
}
}
public void assignNum(){
int temporaryNum1 = getRandom(numberRange());
int temporaryNum2 = getRandom(numberRange());
while(operation == 4 && temporaryNum1 == 0){
temporaryNum1 = getRandom(numberRange());
}
while(operation == 4 && temporaryNum2 == 0){
temporaryNum2 = getRandom(numberRange());
}
if(temporaryNum1 > temporaryNum2)
{
randomNum1 = temporaryNum1;
randomNum2 = temporaryNum2;
}
else
{
randomNum1 = temporaryNum2;
randomNum2 = temporaryNum1;
}
}
public int getRandom(int range){
randomNumber = (int)Math.floor((Math.random()*range)+1);
return randomNumber;
}
}
The reason your questions are not outputting is simple.
public void pickOperation(){
int operation = 0;
System.out.println("1 - Addition\n2 - Subtraction\n3 - Multiplication\n4 - Division ");
operation = input.nextInt();
}
You are creating a local variable, operation, and assigning the input value to it. This means that the field, operation, is never set, so when it comes to the switch statement in your getProblem method, it doesn't output anything because it doesn't match the switch statement.
To fix this, simply remove the int operation = 0; declaration.
Edit
Just noticed the same problem with your pickDifficulty method. I would strongly recommend you have a look at this tutorial on scope in Java.
Explanation of your Problem
Okay. So let's look at your code:
public void pickOperation(){
int operation = 0;
// Declare an int, called 'operation'.
System.out.println("1 - Addition\n2 - Subtraction\n3 - Multiplication\n4 - Division ");
// Set the newly declared value to an int from the keyboard.
operation = input.nextInt();
}
As soon as this method is finished, the value inside operation is destroyed. The reason why it isn't staying in your field int operation, is because you declared a more local operation variable. By removing the int operation = 0; at the start of this method, you force the JVM to look for the next available variable named operation in your class, which is in the field. That's why, when you remove the first assertion statement, your value for operation will stick around.
the problem is : int operation = 0; you need to take the value of the operation in operation variable which you create it in Main
Try this :
import java.util.Random;
import java.util.*;
import java.util.Scanner;
import javax.swing.JOptionPane;
import java.lang.Math;
public class Main {
Scanner input = new Scanner(System.in);
int correctAnswers;
int randomNum1;
int randomNum2;
int choice;
int corrrectAnswers, wrongAnswers;
String playerName = "";
int operation;
int userAnswer;
int correctAnswer = 0;
int userRemainder, correctRemainder;
int x = 0;
int temporaryNum1, temporaryNum2;
int range;
int randomNumber;
public static void main(String args[]) {
Main lab = new Main();
lab.init();
}
public void init() {
getName();
pickDifficulty();
pickOperation();
for (int x = 0; x < 10; x++) {
System.out.println("\t\t\t~~~~~~~PROBLEM NUMBER" + (x + 1) + "~~~~~~~~");
assignNum();
getProblem();
getAnswers();
checkAnswer();
}
}
//GET PLAYER NAME USING PANE
public static String getName() {
String playerName;
playerName = JOptionPane.showInputDialog(null, "Welcome!\nEnter your name and press OK.", "Math Is Super Fun!", JOptionPane.QUESTION_MESSAGE);
System.out.println("Do your best," + playerName + "!");
return playerName;
}
//GET PROBLEM BASED ON OPERATION
public void getProblem() {
switch (operation) {
case 1:
System.out.println(randomNum1 + "+" + randomNum2 + "= ?\n");
correctAnswer = randomNum1 + randomNum2;
break;
case 2:
System.out.println(randomNum1 + "-" + randomNum2 + "= ?\n");
correctAnswer = randomNum1 - randomNum2;
break;
case 3:
System.out.println(randomNum1 + "*" + randomNum2 + "= ?\n");
correctAnswer = randomNum1 * randomNum2;
break;
case 4:
System.out.println(randomNum1 + "/" + randomNum2 + "= ?\n");
correctAnswer = randomNum1 / randomNum2;
correctRemainder = randomNum1 % randomNum2;
break;
}
System.out.print("Answer: ");
userAnswer = input.nextInt();
if (operation == 4) {
System.out.print("Remainder: ");
userRemainder = input.nextInt();
}
// return 0;
}
//PICK DIFFICULTY USING DIALOG
public void pickDifficulty() {
System.out.println("1 - Child's Play\n2 - No Sweat\n3 - Bitter\n4 - Cold-blooded\n5 - Brutal\n6 - Genius");
choice = input.nextInt();
}
//PICK OPERATIONS
public void pickOperation() {
System.out.println("1 - Addition\n2 - Subtraction\n3 - Multiplication\n4 - Division ");
operation = input.nextInt();
}
//GET NUMBER RANGE BASED ON DIFFICULTY
public int numberRange() {
int range = 0;
switch (choice) {
case 1:
range = 100;
break;
case 2:
range = 1000;
break;
case 3:
range = 10000;
break;
case 4:
range = 100000;
break;
case 5:
range = 1000000;
break;
case 6:
range = 10000000;
break;
}
return range;
}
//GET CORRECT RANDOM RESPONSE USING CASE SWITCH BASED ON GETRANDOM METHOD
public void correctResponse() {
String responseCorrect = "";
switch (getRandom(5)) {
case 1:
responseCorrect = "Correct. Keep up the good work!";
break;
case 2:
responseCorrect = "Correct. Keep aiming higher!";
break;
case 3:
responseCorrect = "Correct. Well done!";
break;
case 4:
responseCorrect = "Correct. Nice work!";
break;
case 5:
responseCorrect = "Correct. We're almost there!";
break;
}
System.out.println(responseCorrect);
correctAnswers += 1;
}
//GET WRONG RANDOM RESPONSE USING CASE SWITCH BASED ON GETRANDOM METHOD
public String wrongResponse() {
String responseWrong = "";
switch (getRandom(5)) {
case 1:
responseWrong = "Wrong. Don't give up!";
break;
case 2:
responseWrong = "Wrong. You can do it!";
break;
case 3:
responseWrong = "Wrong. Try again puny human!";
break;
case 4:
responseWrong = "Wrong. You must be really weak at math!";
break;
case 5:
responseWrong = "Wrong. I pity you!";
break;
}
System.out.println(responseWrong);
System.out.println("The correct answer is:" + correctAnswer);
if (operation == 4) {
System.out.println("Correct Remainder: " + correctRemainder);
}
return responseWrong;
}
public void checkAnswer() {
if (operation != 4 && userAnswer == correctAnswer) {
correctResponse();
} else if (operation == 4 && userAnswer == correctAnswer && userRemainder == correctRemainder) {
correctResponse();
} else {
wrongResponse();
}
}
public void assignNum() {
int temporaryNum1 = getRandom(numberRange());
int temporaryNum2 = getRandom(numberRange());
while (operation == 4 && temporaryNum1 == 0) {
temporaryNum1 = getRandom(numberRange());
}
while (operation == 4 && temporaryNum2 == 0) {
temporaryNum2 = getRandom(numberRange());
}
if (temporaryNum1 > temporaryNum2) {
randomNum1 = temporaryNum1;
randomNum2 = temporaryNum2;
} else {
randomNum1 = temporaryNum2;
randomNum2 = temporaryNum1;
}
}
public int getRandom(int range) {
randomNumber = (int) Math.floor((Math.random() * range) + 1);
return randomNumber;
}
private void getAnswers() {
////////////////Not yet implemented";
}
}

Maths operators

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;
}
}

Categories