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. :-)
Related
public static int evaluate(Scanner input)
{
if (input.hasNextInt())
{
return input.nextInt();
}
else
{
String operator = input.next();
int operand1 = evaluate(input);
int 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 int evaluate(String operator, int operand1, int 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 want to take this code and convert it to 2 stacks (one stack for the operators and the other stack for the operands) for using prefix expressions in a user-input GUI with an actionlistener. How can I write the code to convert this code to 2 stacks? By the way, this is homework and I understand that you're not allowed to give me the answers outright, so if you can provide me easy-to-understand pseudo code, that will be much appreciated. Thank you for your help.
Your pseudo is here:
public static int evaluate(Scanner input)
{
if (input.hasNextInt())
{
int stack_top_value=input.nextInt();
stack_for_operand.push(stack_top_value);
return stack_top_value;
}
else
{
String operator = input.next();
stack_for_operator.push(operator);
int operand1 = evaluate(input);
int operand2 = evaluate(input);
return evaluate(operator, operand1, operand2);
}
}
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());
}
}
Okay... I think I might have gone over my head with trying to simplify this code. I place operators such as ( *, +, /, -) in a split. Know i want to call them individually to do their perspective task in a if (operators.equals.(+)){
return num1 + num2. }
then for *, -, / perspectively
how can i do that correctly having using math in my earlier code:
String function = "[+\\-*/]+"; //this
String[] token = input.split(function);//and this
double num1 = Double.parseDouble(token[0]);
double num2 = Double.parseDouble(token[1]);
double answer;
String operator = input.toCharArray()[token[0].length()]+"";
if (operator.matches(function) && (token[0]+token[1]+operator).length()==input.length()) {
System.out.println("Operation is " + operator+ ", numbers are " + token[0] + " and " + token[1]);
} else {
System.out.println("Your entry of " + input + " is invalid");
}
You don't.
String.split only returns the parts of the String that were not matched. If you want to know the matched code, you need to use a more sophisticated regular expression, i.e. the Pattern and Matcher classes, or write your own String tokenization class yourself.
In this example Token is a class you make yourself):
public List<Token> generateTokenList(String input) {
List<Token> = new LinkedList<>();
for(char c : input.toCharArray()) {
if(Character.isDigit(c)) {
// handle digit case
} else if (c == '+') {
// handle plus
} else if (c == '-') {
// handle minus
} else {
/* you get the idea */
}
}
}
There are libraries that do this for you, such as ANTLR but this sounds like a school assignment so you probably have to do this the hard way.
Change your if body to something like
if (operator.matches(function) &&
(token[0] + token[1] + operator).length() == input.length())
{
double result = 0;
if (operator.equals("+")) {
result = num1 + num2;
} else if (operator.equals("-")) {
result = num1 - num2;
} else if (operator.equals("*")) {
result = num1 * num2;
} else if (operator.equals("/")) {
result = num1 / num2;
}
System.out.printf("%.2f %s %.2f = %.2f%n", num1, operator, num2,
result);
}
And your code works as expected.
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);
}
}
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.