private class InputListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
// Create an integer and character stack
Stack<Integer> operandStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
// User input in input text field
String input = inputTextField.getText();
// Create string tokenizer containing string input
StringTokenizer strToken = new StringTokenizer(input);
// Loop while there are tokens
while (strToken.hasMoreTokens())
{
String i = strToken.nextToken();
int operand;
char operator;
try
{
operand = Integer.parseInt(i);
operandStack.push(operand);
}
catch (NumberFormatException nfe)
{
operator = i.charAt(0);
operatorStack.push(operator);
}
}
// Loop until there is only one item left in the
// operandStack. This one item left is the result
while(operandStack.size() > 1)
{
// Perform the operations on the stack
// and push the result back onto the operandStack
operandStack.push(operate(operandStack.pop(),
operandStack.pop(), operatorStack.pop()));
}
// Display the result as a string in the result text field
resultTextField.setText(Integer.toString(operandStack.peek()));
}
// Sum and product computed
public int operate(Integer operand1, Integer operand2, char operator)
{
switch(operator)
{
case '*':
return operand2 * operand1;
case '/':
return operand2 / operand1;
case '%':
return operand2 % operand1;
case '+':
return operand2 + operand1;
case '-':
return operand2 - operand1;
default:
throw new IllegalStateException("Unknown operator " + operator + " ");
}
}
}
The prefix expression code provided is incorrectly evaluating expressions with more than one operator. The expression: * + 16 4 + 3 1 should evaluate to 80 = ((16 + 4) * (3 + 1)), but instead it evaluates to 128, which I think is evaluating as: ((16 + 4) * (3 + 1) + (16 * 3)). How do I edit the code to correct this problem? Thank you for your help.
In prefix evaluation,Important thing to remember is
operand 1= pop();
operand 2= pop();
and say the operator is -
The value that is pushed is operand 1 - operand 2 and not operand 2 - operand 1
But something else is causing * + 16 4 + 3 1 to evaluate to 128.
I used the following algo for evaluating in java and it works fine
1.Take the prefix expression as a string in a variable with characters separated by single space.
2.Traverse the string from index length-1 to 0
3.If its a number, perform push ,and if its a multidigit number,first obtain the full number and then push it
4.If its an operator then simply do the thing which i mentioned in beginning of the answer.
It is a simple code.
import java.io.*;
import java.util.*;
class PREFIXEVAL
{
public static void main(String []args)throws IOException
{
String p,n="";StringBuffer b;int i,op1,op2;char c;Stack<Integer> s=new Stack<Integer>();
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter the prefix expression separated by spaces");
p=br.readLine();
i=p.length()-1;
while(i>=0)
{
c=p.charAt(i);
if(c>=48&&c<=57)
n=n+c;
else if(c==' '&&!n.equals(""))
{/*handles both single and multidigit numbers*/
b=new StringBuffer(n);b.reverse();n=b.toString();
s.push(Integer.parseInt(n));n="";
}
else
{
if(c=='+')
{
op1=s.pop();
op2=s.pop();
s.push(op1+op2);
}
else if(c=='-')
{
op1=s.pop();
op2=s.pop();
s.push(op1-op2);
}
else if(c=='*')
{
op1=s.pop();
op2=s.pop();
s.push(op1*op2);
}
else if(c=='%')
{
op1=s.pop();
op2=s.pop();
s.push(op1%op2);
}
else if(c=='/')
{
op1=s.pop();
op2=s.pop();
s.push(op1/op2);
}
}
i--;
}
System.out.println("the prefix expression evaluates to "+s.peek());
}
}
Related
I got most of the code out of the text book and every thing seems to be working. For example if I have the postfix 5 2 + it would give me 7, which is correct but if I have 5 2 4 * / 7 - then it throws the illegal input exception. When I got rid of the illegal input exception, it works but doesn't give the right answer.
import java.util.*;
import java.util.regex.Pattern;
//Here is my class and main method
public class postFix {
public static final Pattern UNSIGNED_DOUBLE = Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][-+]?\\d+)?.*?");
public static final Pattern CHARACTER = Pattern.compile("\\S.*?");
public static Double postfixEvaluate (String expression) {
Stack<Double> numbers = new Stack<Double>( ); //Stack for numbers
Stack<Character> operators = new Stack<Character>( ); //Stack for ops
Scanner input = new Scanner(expression);
String next;
while (input.hasNext()) //Iterator is used (hasNext)
{
if (input.hasNext(UNSIGNED_DOUBLE))
{ // if next input is a number
next = input.findInLine(UNSIGNED_DOUBLE);
numbers.push(new Double(next)); //adding nums to the number stack
}
else
{ //The next input is an operator
next = input.findInLine(CHARACTER);
switch (next.charAt(0))
{
case '+':
case '-':
case '*':
case '/':
operators.push(next.charAt(0)); //adding operators to operator stack
break;
case ')':
evaluateStackTops(numbers, operators);
break;
case '(':
break;
default: //Illegal Character
throw new IllegalArgumentException("Illegal Character");
}
}
}
//This what seems to be throwing the exception but I got this right out of the book
if (numbers.size() != 1)
throw new IllegalArgumentException("Illegal Input");
return numbers.pop( );
}
public static void evaluateStackTops (Stack<Double> numbers, Stack<Character> operators)
{
double operand1 , operand2;
//check that the stacks have enough items, and get the two operands
if ((numbers.size()<2)||(operators.isEmpty())) {
throw new IllegalArgumentException("Illegal Expression");}
operand2 = numbers.pop();
operand1 = numbers.pop();
//carry out an operation based on the operator on top of the stack
for (int i = 0; i < numbers.size(); i++) {
switch (operators.pop()) {
case '+':
numbers.push(operand1 + operand2);
break;
case '-':
numbers.push(operand1 - operand2);
break;
case '*':
numbers.push(operand1 * operand2);
break;
case '/':
numbers.push(operand1 / operand2);
break;
default:
throw new IllegalArgumentException("Illegal Operator");
}
}
public static void main(String[] args) {
//String expression;
//Scanner input = new Scanner(expression);
System.out.println(postFix.postfixEvaluate("(2 3 5 * / )" ));
}
}
Your algorithm is flawed. All it does is build stacks of operators and operands, and then evaluate the expression backwards. That's never going to work.
I don't understand why you're even checking for parentheses. There are no parentheses in postfix expressions, because the conversion from infix to postfix has already removed the parentheses.
Also, there is no need for a stack of operators. The whole idea of postfix is that you can evaluate each operator as you encounter it, and push the result back onto the stack.
The basic algorithm is:
while not end of input
read next token
if token is a number
push on numbers stack
else if token is operator
pop value2 and value1 from stack
result = evaluate value1 <operator> value2
push result to numbers stack
else
invalid input
end while
// at this point, there should be 1 value on numbers stack
So when evaluating 5 2 4 * / 7 -, the sequence is:
push 5
push 2
push 4
// operator * read here
pop 4
pop 2
evaluate 2 * 4
push 8
// operator / read here
pop 8
pop 5
evaluate 5/8
push 0.625
push 7
// operator - read here
pop 7
pop 0.625
evaluate 0.625 - 7
push -6.375
// end of input here
pop final result
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)
I have the following pseudocode and need to write a java method to evaluate a prefix expression:
Algorithm valueOfPrefixExpression(prefixExpression)
Input: a valid positive-integer arithmetic expression in prefix form
Return value: the value of the prefix expression
if next token is an integer
return the integer
else
Read an operator, say op
firstOperand gets valueOfPrefixExpression(remainingExpression)
secondOperand gets valueOfPrefixExpression(remainingExpression)
return firstOperand op secondOperand
endif
How can I write this method? I tried this and I think it could be right but I am getting a "missing return statement" error so I can't compile. Assume method is only called if args has 1 or more elements. (no empty arrays)
public static int prefixAlgorithm(String[] args) {
for (int i = 0; i < args.length; i++) {
if (!args[i].equals("+") && !args[i].equals("-")
&& !args[i].equals("*") && !args[i].equals("/")) {
int operand = parseInt(args[i]);
return operand;
} else {
int firstOperand = prefixAlgorithm(Arrays.copyOfRange(args, i, (args.length - 1)));
int secondOperand = prefixAlgorithm(Arrays.copyOfRange(args, i, (args.length - 1)));
if (args[i].equals("+")) {
return firstOperand + secondOperand;
} else if (args[i].equals("-")) {
return firstOperand - secondOperand;
} else if (args[i].equals("*")) {
return firstOperand * secondOperand;
} else if (args[i].equals("/")) {
return firstOperand / secondOperand;
}
}
}
}
PrefixEvaluator with input and Scanner:
import java.util.*;
public class PrefixEvaluator {
public static void main(String[] args) {
Scanner console = 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(console));
}
// 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);
}
}
}
PrefixEvaluator with no input and queue:
import java.util.*;
public class PrefixEvaluator {
public static void main(String[] args) {
String input = "- * + 4 3 2 5";
String[] expression = input.split ( " " );
Queue<String> expressionQueue = new LinkedList<String>();
for (String element : expression)
{
expressionQueue.add ( element );
}
System.out.println("value = " + evaluate(expressionQueue));
}
// pre : input contains a legal prefix expression
// post: expression is consumed and the result is returned
public static double evaluate(Queue <String> input) {
if(input.peek ( ) != null && input.peek ( ).matches ( "^(-?)\\d+$" ))
{
return Long.parseLong ( input.poll ( ) );
}
else
{
String operator = input.poll();
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/O Example:
This program evaluates prefix expressions
for operators +, -, *, / and %
expression? - * + 4 3 2 5
value = 9.0
Documentation:
Queues: Queue (Java Platform SE 7 )
Patterns: Pattern (Java Platform SE 7 )
Your compilation problem is because you don't have a guaranteed return from the method. If arg[i] is something other than one of the four expected characters for the entire array, you'll simply run off the bottom of the function.
You may believe that the input will always conform to expectations, but compilerse know better than to trust humans. :-)
I'm trying to make a recursive program that reads and evaluates fully parenthesized arithmetic expressions. The program was already made, my task is to make the method evaluates recursively. However, I'm having a bit of difficulty doing this. I have gotten much done, but I'm now getting an error - java.lang.NumberFormatException - and I can't seem to figure out why and where it's coming from. Could someone please help me as I have been at this for a week and need some help desperately.
Heres my code:
package q2;
// FILE: EvaluateDemonstration.java
// This program reads a reads and evaluates fully parenthesized arithmetic
// expressions. The purpose is to illustrate a fundamental use of stacks.
import java.util.Scanner;
import java.util.regex.Pattern;
public class RecursiveEvaluateDemonstration
{
public static void main(String[ ] args)
{
Scanner stdin = new Scanner(System.in);
String expression;
double answer;
System.out.println("Please type an arithmetic expression made from");
System.out.println("unsigned numbers and the operations + - * /.");
System.out.println("The expression must be fully parenthesized.");
do
{
System.out.print("Your expression: ");
expression = stdin.nextLine( );
try
{
answer = evaluate(expression,0,0,0);
System.out.println("The value is " + answer);
}
catch (Exception e)
{
System.out.println("Error." + e.toString( ) + " Help");
}
}
while (query(stdin, "Another string?"));
System.out.println("All numbers are interesting.");
}
public static boolean query(Scanner input, String prompt)
{
String answer;
System.out.print(prompt + " [Y or N]: ");
answer = input.nextLine( ).toUpperCase( );
while (!answer.startsWith("Y") && !answer.startsWith("N"))
{
System.out.print("Invalid response. Please type Y or N: ");
answer = input.nextLine( ).toUpperCase( );
}
return answer.startsWith("Y");
}
public static double evaluate(String s, int i,int j, int charIndex)
// Precondition: The string is a fully parenthesized arithmetic expression
// formed from non-negative numbers, parentheses, and the four operations
// +, -, *, and /.
// Postcondition: The string has been evaluated and the value returned.
// Exceptions: Can throw an NumberFormatException if the expression contains
// characters other than digits, operations, parentheses and whitespace.
// Can throw IllegalArgumentException if the input line is an
// illegal expression, such as unbalanced parentheses or a division by zero.
{
double[] numbers = new double[3] ;
Character[] operations = new Character[1];
String next = "";
int length = s.length();
char first;
int numIndex = i;
int operatIndex = j;
if (charIndex < length)
{
if (Character.isDigit(s.charAt(charIndex))) //|| s.charAt(charIndex) == '.' )
{
next += s.charAt(charIndex);
}
else
{
first = s.charAt(charIndex);
switch (first)
{
case '+': // Addition
case '-': // Subtraction
case '*': // Multiplication
case '/': // Division
numbers[numIndex]=(new Double(next));
System.out.println(numbers[numIndex]);
operations[operatIndex] = first;
break;
case ')': // Right parenthesis
evaluateStackTops(numbers, operations);
break;
case '(': // Left parenthesis
break;
default : // Illegal character
throw new IllegalArgumentException("Illegal character");
}
}
evaluate(s, ++numIndex, operatIndex+1, charIndex+1);
}
if (numbers.length != 3)
throw new IllegalArgumentException("Illegal input expression");
return numbers[2];
}
public static void evaluateStackTops(double[] numbers, Character[] operations)
// Precondition: The top of the operations stack contains +, -, *, or /, and
// the numbers stack contains at least two numbers.
// Postcondition: The top two numbers have been popped from the numbers stack, and the
// top operation has been popped from the operations stack. The two numbers have been
// combined using the operation (with the second number popped as the left operand).
// The result of the operation has then been pushed back onto the numbers stack.
// Exceptions: Throws an IllegalArgumentException if the stacks are illegal or if the
// operation results in a division by zero.
{
double operand1, operand2;
// Check that the stacks have enough items, and get the two operands.
if ((numbers.length < 2))
throw new IllegalArgumentException("Illegal expression");
operand2 = numbers[1];
operand1 = numbers[0];
// Carry out an action based on the operation on the top of the stack.
switch (operations[0])
{
case '+': numbers[2] = (operand1 + operand2);
break;
case '-': numbers[2] = (operand1 - operand2);
break;
case '*': numbers[2]= (operand1 * operand2);
break;
case '/': // Note: A division by zero results in POSTIVE_INFINITY or
// NEGATIVE_INFINITY.
numbers[2] = (operand1 / operand2);
break;
default : throw new IllegalArgumentException("Illegal operation");
}
}
// These patterns are from Appendix B of Data Structures and Other Objects.
// They may be used in hasNext and findInLine to read certain patterns
// from a Scanner.
public static final Pattern CHARACTER =
Pattern.compile("\\S.*?");
public static final Pattern UNSIGNED_DOUBLE =
Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][-+]?\\d+)?.*?");
}
Here's the trace:
Exception in thread "main" java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.valueOf(Unknown Source)
at java.lang.Double.<init>(Unknown Source)
at q2.RecursiveEvaluateDemonstration.evaluate(RecursiveEvaluateDemonstration.java:94)
at q2.RecursiveEvaluateDemonstration.evaluate(RecursiveEvaluateDemonstration.java:107)
at q2.RecursiveEvaluateDemonstration.evaluate(RecursiveEvaluateDemonstration.java:107)
at q2.RecursiveEvaluateDemonstration.main(RecursiveEvaluateDemonstration.java:29)
You're probably getting the number format exception because you're doing
case '+': // Addition
case '-': // Subtraction
case '*': // Multiplication
case '/': // Division
numbers[numIndex]=(new Double(next));
But at this point, the next could be the empty string "", so it will fail with that.
Add
e.printStackTrace();
to the catch block in the main method and run the program again with same input to receive the stacktrace, then share the stacktrace here.
I'm going insane..I'm so close to getting this code to work the way I want to I just can't figure it out. I'm trying to solve a postfix equation for ex. 3 2 + , this equals 5. When I put for example
"3 2 +" in the mainmethod it works fine but as soon as I enter a 3rd digit like "3 2 + 2 *" (which equals 10) I get a arrayoutofboundserror relating back to number2 = s.pop() as you will see in the code below. Any help is greatly appreciated.
Heres the postfix meethod:
public int PostfixEvaluate(String e){
int number1;
int number2;
int result=0;
String[] tokens = e.split(" ");
for(int j = 0; j < tokens.length; j++){
String token = tokens[j];
if (!"+".equals(token) && !"*".equals(token) && !"-".equals(token) && !"/".equals(token)) {
s.push(Integer.parseInt(token));
} else {
String Operator = tokens[j];
number1 = s.pop();
number2 = s.pop();
if (Operator.equals("/")){
result = number1 / number2;}
else if(Operator.equals("*")){
result = number1 * number2;}
else if(Operator.equals("+")){
result = number1 + number2;}
else if(Operator.equals("-")){
result = number1 - number2;}
else System.out.println("Illeagal symbol");
}
s.push(result);
s.pop();
}
//s.pop();
System.out.println("Postfix Evauation = " + result);
return result;
}
public static void main(String[] args) {
Stacked st = new Stacked(100);
//String y = new String("((z * j)/(b * 8) ^2");
String x = new String("2 2 2 * +");
TestingClass clas = new TestingClass(st);
//clas.test(y);
clas.PostfixEvaluate(x);
}
}
/**
* Evaluate postfix arithmetic expression
*
* #example "1 12 23 + * 4 5 / -" => 34.2
* #author Yong Su
*/
import java.util.Stack;
class PostfixEvaluation {
public static void main(String[] args) {
String postfix = "1 12 23 + * 4 5 / -";
Double value = evaluate(postfix);
System.out.println(value);
}
/**
* Evaluate postfix expression
*
* #param postfix The postfix expression
*/
public static Double evaluate(String postfix) {
// Use a stack to track all the numbers and temporary results
Stack<Double> s = new Stack<Double>();
// Convert expression to char array
char[] chars = postfix.toCharArray();
// Cache the length of expression
int N = chars.length;
for (int i = 0; i < N; i++) {
char ch = chars[i];
if (isOperator(ch)) {
// Operator, simply pop out two numbers from stack and perfom operation
// Notice the order of operands
switch (ch) {
case '+': s.push(s.pop() + s.pop()); break;
case '*': s.push(s.pop() * s.pop()); break;
case '-': s.push(-s.pop() + s.pop()); break;
case '/': s.push(1 / s.pop() * s.pop()); break;
}
} else if(Character.isDigit(ch)) {
// Number, push to the stack
s.push(0.0);
while (Character.isDigit(chars[i]))
s.push(10.0 * s.pop() + (chars[i++] - '0'));
}
}
// The final result should be located in the bottom of stack
// Otherwise return 0.0
if (!s.isEmpty())
return s.pop();
else
return 0.0;
}
/**
* Check if the character is an operator
*/
private static boolean isOperator(char ch) {
return ch == '*' || ch == '/' || ch == '+' || ch == '-';
}
}
The number1 assignment should be after the number2 assignment. Remember that s.pop() will remove and return the number that is on the top.
number2 = s.pop();
number1 = s.pop();
Are you popping immediately after pushing?
s.push(result);
s.pop();
There is another logical error in this solution. You need to do:
number2 = s.pop();
number1 = s.pop();
your solution won't work if you had 32/ because you will evaluate it to 2/3.