How do I evaluate math expression from an editText? - java

I worked on a simple calculator app that does not pile up an expression like google calculator. Instead it stores the result in an operand when an operation button is pressed and so it does not follow BODMAS precedence rules. Like if I perform 2 + 2 / 2 I get 4 as the result whereas the result should be 3 as the division is performed first
Is there a way to take input as a whole expression and then evaluate it collectively?
Are there any predefined classes that I can use that are included in java?
The code for the onClickListeners of operators and calculation performing function is:
View.OnClickListener opListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
Button b = (Button) view;
String op = b.getText().toString();
String value = newNumber.getText().toString();
try {
Double doubleValue = Double.valueOf(value);
performOperation(doubleValue, op);
} catch (NumberFormatException e) {
newNumber.setText("");
}
pendingOperation = op;
displayOperation.setText(pendingOperation);
}
};
private void performOperation(Double value, String operation) {
if (operand1 == null) {
operand1 = value;
} else {
if (pendingOperation.equals("=")) {
pendingOperation = operation;
}
switch (pendingOperation) {
case "=":
operand1 = value;
break;
case "/":
if (value == 0) {
operand1 = 0.0;
Toast.makeText(this,"Cannot Divide By Zero, Resetting value to zero",Toast.LENGTH_LONG).show();
} else {
operand1 /= value;
}
break;
case "*":
operand1 *= value;
break;
case "+":
operand1 += value;
break;
case "-":
operand1 -= value;
break;
}
}
result.setText(operand1.toString());
newNumber.setText("");
}

Related

Create a GUI that allows user to enter prefix expressions and displays result in GUI

import java.util.*;
public class PrefixExpression
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("This program evaluates prefix expressions ");
System.out.println("for operators *, /, %, +, and - ");
System.out.print("expression? ");
System.out.println("value = " + evaluate(keyboard));
}
// pre : input contains a legal prefix expression
// post: expression is consumed and the result is returned
public static double evaluate(Scanner input)
{
if (input.hasNextDouble())
{
return input.nextDouble();
}
else
{
String operator = input.next();
double operand1 = evaluate(input);
double operand2 = evaluate(input);
return evaluate(operator, operand1, operand2);
}
}
// pre : operator is one of *, /, %, + or -
// post: returns the result of applying the given operator to
// the given operands
public static double evaluate(String operator, double operand1, double operand2)
{
if (operator.equals("*"))
{
return operand1 * operand2;
}
else if (operator.equals("/"))
{
return operand1 / operand2;
}
else if (operator.equals("%"))
{
return operand1 % operand2;
}
else if (operator.equals("+"))
{
return operand1 + operand2;
}
else if (operator.equals("-"))
{
return operand1 - operand2;
}
else
{
throw new RuntimeException("illegal operator " + operator);
}
}
}
I need help creating a GUI for this prefix expression program. The GUI allows the user to enter prefix expressions and the results are displayed in the GUI.
Example:
Enter Expression: * + 16 4 + 3 1
Result: 80
Thank you for your help.

Java infix calculator logic

I am having trouble figuring out the logic for an infix calculator that is dynamic. I am able to accommodate string values with 5 elements, such as "1 + 1", but I cannot compute strings with more than 5 elements (ie: "1 + 2 + 3 + 4").
This is my process
import java.util.StringTokenizer;
public static int calculate(String input)
{
int lhs = 0;
int rhs = 0;
int total = 0;
char operation = ' ';
int intOne, intTwo;
StringTokenizer st = new StringTokenizer(input);
/*
* this block is chosen if there are no operations
*/
// block of if statement code for inputs less than or equal to
// 5 characters.
/*
* this block generates the correct number if there is more than
* one operator in the equation.
*/
}else if(input.length() > 5){
int firstValue = 0;
int latterValue = 0;
while(st.hasMoreTokens()){
/*
* method that assigns the left and right sides
*/
//assigns values to the first equation
int firstToken = Integer.parseInt(st.nextToken());
String opToken = st.nextToken();
int latterToken = Integer.parseInt(st.nextToken());
//returns a value for the first equation
firstValue = assignSides(firstToken, opToken, latterToken);
// takes in the next operator
if(st.nextToken().equals("+")){
operation = '+';
}else if(st.nextToken().equals("-")){
operation = '-';
}else if(st.nextToken().equals("*")){
operation = '*';
}else if(st.nextToken().equals("/")){
operation = '/';
}
// assigns values to the latter equation
firstToken = Integer.parseInt(st.nextToken());
opToken = st.nextToken();
latterToken = Integer.parseInt(st.nextToken());
//returns a value for the latter equation
latterValue = assignSides(firstToken, opToken, latterToken);
/*
* decides how to add the two equations
*/
switch(operation){
case '+': total = firstValue + latterValue;
break;
case '-': total = firstValue - latterValue;
break;
case '*': total = firstValue * latterValue;
break;
case '/': total = firstValue / latterValue;
break;
default: System.out.println("cannot compute");
break;
}
if(st.hasMoreTokens()){
//makes the total the first value
total = firstValue;
if(st.nextToken().equals("+")){
operation = '+';
}else if(st.nextToken().equals("-")){
operation = '-';
}else if(st.nextToken().equals("*")){
operation = '*';
}else if(st.nextToken().equals("/")){
operation = '/';
}
}
}
}
return total;
}
public static int assignSides(int firstToken, String opToken, int latterToken)
{
int lhs=0;
int rhs = 0;
int sum = 0;
char operation = ' ';
/*
* converts the string into a character
*/
if(opToken.equals("+")){
operation = '+';
}else if(opToken.equals("-")){
operation = '-';
}else if(opToken.equals("*")){
operation = '*';
}else if(opToken.equals("/")){
operation = '/';
}
rhs = latterToken;
/*
* interprates the character as a function
*/
switch(operation){
case '+': sum = lhs + rhs;
break;
case '-': sum = lhs - rhs;
break;
case '*': sum = lhs * rhs;
break;
case '/': sum = lhs / rhs;
break;
default: System.out.println("cannot compute");
break;
}
return sum;
}
Can I get help me with the error in my logic?
When calculating for more than 3 symbols (not counting spaces), as in "1 + 2 + 3",
you have to calculate in this order: 1 + (2 + 3).
You have to split up the first 1 and the remainig part "2 + 3", and pass the remaining part to the calculate method again. Something like:
int firstPart = ...; // evaluation of "1"
int secondPart = calculate("2 + 3");
int total = firstPart + secondPart;

Java calculate numbers in a string

I'm making a calculator program that can read in a string like this:
67+12-45
How can I perform the function that the string is intending to do? Here's what I've tried so far:
public static int calculate(String expression, int num1, int num2)
{
int answer = 0;
switch(expression)
{
case "+":
if(answer != 0)
{
answer = answer + num1 + num2;
}
else
{
answer = num1 + num2;
}
break;
case "-":
if(answer != 0)
{
answer = answer + (num1 - num2);
}
else
{
answer = num1 - num2;
}
break;
case "*":
if(answer != 0)
{
answer = answer + (num1 * num2);
}
else
{
answer = num1 * num2;
}
break;
case "/":
if(answer != 0)
{
answer = answer + (num1 / num2);
}
else
{
answer = num1 / num2;
}
break;
case "%":
if(answer != 0)
{
answer = answer + (num1 % num2);
}
else
{
answer = num1 % num2;
}
break;
}
return answer;
}
Is there a simpler way to perform the function intended in the string?
the easiest way to achieve this is using eval, you can do this:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("67+12-45"); //you can insert any expression here
This talk describes an Object Oriented solution to this problem:
http://youtu.be/4F72VULWFvc?t=7m40s
Essentially, you can parse the string into an expression tree that can be evaluated.

Variable is not used in Android Calculator

Using eclipse, first of all. I'm building an Android calculator. I have all my code, except there's a problem. One of my variables is not being used. My total1 variable is basically the counter for the program. When I add two numbers up and press equals, it always prints "0.0" and that's the value of total1. That means for some reason, it never changed throughout the whole program. I even tested this by using a print statement. I changed the value of total1 and it would print that value I assigned it to. What could be the problem?
public class HelloAndroidActivity extends Activity {
public EditText display;
String display1;
double displayValue;
// Program is printing out total1, as if it weren't maninpulated in the code
double total1 = 0.0;
double total2 = 0.0;
char theOperator;
public String buttonText;
public Button ButtonAdd, ButtonEqual, ButtonMultiply, ButtonDivide, ButtonMinus;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
display = (EditText) findViewById(R.id.editText1);
// Could it have something to do with this if statement?
if (display.length() != 0) {
display1 = display.getText().toString();
displayValue = Double.parseDouble(display1);
}
}
//Get the operator of the multiply, divide, subtract, add buttons when they are clicked and then do the following
public void getOperator(String btnText) {
theOperator = btnText.charAt(0);
total1 += displayValue;
display.setText("");
}
// Display a string in the box when a number button is clicked
public void onClick(View v) {
switch (v.getId()) {
case R.id.bOne:
display.append("1");
break;
case R.id.bTwo:
display.append("2");
break;
case R.id.bThree:
display.append("3");
break;
case R.id.bFour:
display.append("4");
break;
case R.id.bFive:
display.append("5");
break;
case R.id.bSix:
display.append("6");
break;
case R.id.bSeven:
display.append("7");
break;
case R.id.bEight:
display.append("8");
break;
case R.id.bNine:
display.append("9");
break;
case R.id.bZero:
display.append("0");
break;
case R.id.bPoint:
display.append(".");
break;
case R.id.bClear:
total2 = 0.0;
display.setText("");
break;
case R.id.bAdd:
buttonText = "+";
ButtonAdd = (Button) findViewById(R.id.bAdd);
ButtonAdd.setText(buttonText);
getOperator(buttonText);
break;
case R.id.bMinus:
buttonText = "-";
ButtonMinus = (Button) findViewById(R.id.bMinus);
ButtonMinus.setText(buttonText);
getOperator(buttonText);
break;
case R.id.bMultiply:
buttonText = "*";
ButtonMultiply = (Button) findViewById(R.id.bMultiply);
ButtonMultiply.setText(buttonText);
getOperator(buttonText);
break;
case R.id.bDivide:
buttonText = "/";
ButtonDivide = (Button) findViewById(R.id.bDivide);
ButtonDivide.setText(buttonText);
getOperator(buttonText);
break;
// Here's the equals button. When I click it it prints out "0.0", the value of total1, instead of adding the total below
case R.id.bEqual:
switch (theOperator) {
case '+':
total2 = total1 + displayValue;
break;
case '-':
total2 = total1 - displayValue;
break;
case '*':
total2 = total1 * displayValue;
break;
case '/':
total2 = total1 / displayValue;
break;
}
display.setText(Double.toString(total2));
total1 = 0.0;
break;
}
}
}
You are trying to add displayValue in your get operator method but you have not changed this value. You should be paring this value from the display before adding it to total1 It should be like this:
public void getOperator(String btnText){
theOperator = btnText.charAt(0);
total1+=Double.parseDouble(display.getText().ToString());
display.setText("");
}
Or like this if you need to save the current display value:
public void getOperator(String btnText){
theOperator = btnText.charAt(0);
displayValue = Double.parseDouble(display.getText().ToString());
total1+=displayValue;
display.setText("");
}
I see only one location where your total1 variable is modified, and there it has the value of displayValue added to it. displayValue is only modified once, in your onCreate method (called just once per Activity lifecycle) where it is loaded from the contents of the editText1 control (which we don't have the source for).
So in short I'm not surprised total1 is not being modified. It's a matter of checking the whole logic flow of your app.

Stack Calculator: Trouble evaluating postfix expression because of casting issue

I'm working on a homework assignment that asks me to create a calculator that changes the expression given to it from infix to postfix to then evaluate. I must do so using stacks but may choose any stack implementation I want as long as I don't use the java.util.Stack from the JCF. I chose a referenced based stack.
The problem I'm having is in my evaluatePostfix method. In order to evaluate the expression I had to cast my operand variables as Integers but eclipse doesn't seem to like that. I keep getting a "java.lang.Character cannot be cast to java.lang.Integer" error. I'm not sure how to fix this issue. Does anyone have any insight?
Here is my code:
public class InfixToPostfixAndEvaluateCalculator {
private String infix;
private String postfix;
private int result;
public InfixToPostfixAndEvaluateCalculator() {
infix=null;
postfix=null;
result=0;
}
public InfixToPostfixAndEvaluateCalculator(String infix) {
this.infix=infix;
postfix=null;
result=0;
}
public String getInfix() {
return infix;
}
public String getPostfix() {
return postfix;
}
public int getresult() {
return result;
}
public void setInfix(String infix) {
this.infix=infix;
}
public void setPostfix(String postfix) {
this.postfix=postfix;
}
public String toString() {
return " Infix: "+infix+"\n Postfix: "+postfix+"\n Result: "+result+"\n";
}
public String infixToPostfix() { //Carrano 2nd ed. p.354
//opStack is a stack of Character objects, such as '+','-','*','/', and ')'
StackInterface opStack=new StackReferenceBased();
String postfixExp=""; //the expression to be built in this method
//for each character ch in the string infix
for (int i=0; i<infix.length(); i++) {
char ch=infix.charAt(i);
switch (ch) {
//if ch is an operator
case '+': case '-': case '*': case '/':
while ( (!opStack.isEmpty())
&& (!opStack.peek().equals('('))
&& (precedence(ch) <= precedence((Character)opStack.peek()))){
postfixExp = postfixExp + opStack.pop();
}
opStack.push(ch);
break;
case '(': //add to stack
opStack.push(ch);
break;
case ')': //start popping things off the stack until you find opening parenthesis, use peak
while (!((Character)opStack.peek()).equals('(')){
postfixExp = postfixExp + opStack.pop();
}//end while
opStack.pop();
break;
default: //ch is an operand
postfixExp = postfixExp + ch;
break;
}//end of switch
}//end of for
System.out.println("End of for loop.");
//append to postfixExp the operators remaining in the stack
while (! opStack.isEmpty()) {
postfixExp=postfixExp+((Character) opStack.pop()).charValue();
}//end of while
postfix=postfixExp; //update the instance variable
return postfixExp;
}//end of infixToPostfix()
//little helper function to determine precedence value of an operator
// *,/ have value of, say 20
// +,- have value of, say 10
private int precedence(char ch) {
int prec = 20;
int prec2 = 10;
if (ch == '*' || ch == '/'){
return prec;
}
if (ch == '+' || ch == '-'){
return prec2;
}
return -1;
}
public int evaluatePostfix() { //Carrano 2nd ed. pp.350-351
//valueStack is a stack of Integer objects:
StackInterface valueStack=new StackReferenceBased();
//variables for the operands:
int operand1, operand2;
//for each character ch in the string postfix
for (int i=0; i<postfix.length(); i++) {
char ch=postfix.charAt(i);
switch (ch) {
//if ch is an operator
case '+':
operand2 = (Integer)valueStack.pop();
operand1 = (Integer)valueStack.pop();
result = operand1 + operand2;
valueStack.push(result);
break;
case '-':
operand2 = (Integer)valueStack.pop();
operand1 = (Integer)valueStack.pop();
result = operand1 - operand2;
valueStack.push(result);
break;
case '*':
operand2 = (Integer)valueStack.pop();
operand1 = (Integer)valueStack.pop();
result = operand1 * operand2;
valueStack.push(result);
break;
case '/':
operand2 = (Integer)valueStack.pop();
operand1 = (Integer)valueStack.pop();
result = operand1 / operand2;
valueStack.push(result);
break;
default: //ch is an operand
valueStack.push(ch);
break;
}//end of switch
}//end of for
//at the end, the value of the expression will be on the top of the stack
result=((Integer) valueStack.pop()).intValue();
return result;
}//end of evaluatePostfix()
} // end StackTest
Yes, you cannot cast Character to Integer.
To do that you can use,
Integer.parseInt(String.valueOf(valueStack.pop()));
parseInt doesn't take Character as argument so, you have to convert first into String and then to Integer.
there is a function to get the numeric int value of a Unicode character
Character.getNumericValue( ch );
hopefully the StackInterface supports type-information
this would prevent dozens of (Integer)-casts
StackInterface<Integer> valueStack = new StackReferenceBased<Integer>();

Categories

Resources