I have written this code for Bodmas, but getting some error in this. If I do 3-5+9, it will result in 3.04.0.
It just start concatenating, though it works for all other operations like *, / and -, please help.
public static String calculation(BODMASCalculation bodmas, String result) {
while (bodmas.hasMatch()) {
double value, leftOfOperator = bodmas.getLeft();
char op = bodmas.getOperator();
double rightOfOprator = bodmas.getRight();
switch (op) {
case '/':
if(rightOfOprator == 0) //Divide by 0 generates Infinity
value = 0;
else
value = leftOfOperator / rightOfOprator;
break;
case '*':
value = leftOfOperator * rightOfOprator;
break;
case '+':
value = leftOfOperator + rightOfOprator;
break;
case '-':
value = leftOfOperator - rightOfOprator;
break;
default:
throw new IllegalArgumentException("Unknown operator.");
}
result = result.substring(0, bodmas.getStart()) + value + result.substring(bodmas.getEnd());
bodmas = new BODMASCalculation(result);
}
return result;
}
Another function is:-
public boolean getMatchFor(String text, char operator) {
String regex = "(-?[\\d\\.]+)(\\x)(-?[\\d\\.]+)";
java.util.regex.Matcher matcher = java.util.regex.Pattern.compile(regex.replace('x', operator)).matcher(text);
if (matcher.find()) {
this.leftOfOperator = Double.parseDouble(matcher.group(1));
this.op = matcher.group(2).charAt(0);
this.rightOfOprator = Double.parseDouble(matcher.group(3));
this.start = matcher.start();
this.end = matcher.end();
return true;
}
return false;
}
I have a solution by adding
String sss = null;
if(op == '+' && !Str.isBlank(result.substring(0, bodmas.getStart())) && value >= 0)
sss = "+";
else
sss = "";
result = result.substring(0, bodmas.getStart()) + sss + value + result.substring(bodmas.getEnd());
But don't want to do that, I want this to work for all the operators.
import java.util.Stack;
public class EvaluateString
{
public static int evaluate(String expression)
{
char[] tokens = expression.toCharArray();
// Stack for numbers: 'values'
Stack<Integer> values = new Stack<Integer>();
// Stack for Operators: 'ops'
Stack<Character> ops = new Stack<Character>();
for (int i = 0; i < tokens.length; i++)
{
// Current token is a whitespace, skip it
if (tokens[i] == ' ')
continue;
// Current token is a number, push it to stack for numbers
if (tokens[i] >= '0' && tokens[i] <= '9')
{
StringBuffer sbuf = new StringBuffer();
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')
sbuf.append(tokens[i++]);
values.push(Integer.parseInt(sbuf.toString()));
}
// Current token is an opening brace, push it to 'ops'
else if (tokens[i] == '(')
ops.push(tokens[i]);
// Closing brace encountered, solve entire brace
else if (tokens[i] == ')')
{
while (ops.peek() != '(')
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
ops.pop();
}
// Current token is an operator.
else if (tokens[i] == '+' || tokens[i] == '-' ||
tokens[i] == '*' || tokens[i] == '/')
{
// While top of 'ops' has same or greater precedence to current
// token, which is an operator. Apply operator on top of 'ops'
// to top two elements in values stack
while (!ops.empty() && hasPrecedence(tokens[i], ops.peek()))
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been parsed at this point, apply remaining
// ops to remaining values
while (!ops.empty())
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Top of 'values' contains result, return it
return values.pop();
}
// Returns true if 'op2' has higher or same precedence as 'op1',
// otherwise returns false.
public static boolean hasPrecedence(char op1, char op2)
{
if (op2 == '(' || op2 == ')')
return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
return false;
else
return true;
}
// A utility method to apply an operator 'op' on operands 'a'
// and 'b'. Return the result.
public static int applyOp(char op, int b, int a)
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new
UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}
// Driver method to test above methods
public static void main(String[] args)
{
System.out.println(EvaluateString.evaluate("10 + 2 * 6"));
System.out.println(EvaluateString.evaluate("100 * 2 + 12"));
System.out.println(EvaluateString.evaluate("100 * ( 2 + 12 )"));
System.out.println(EvaluateString.evaluate("100 * ( 2 + 12 ) / 14"));
}
}
The Java Scripting API allows you to pass parameters from Java application to the script engine and vice versa.
You can use Javax ScriptEngine to pass values from your app to a script.
And using it's eval() method, you can give it a mathematical expression in the form of a string and it will do the the math for you... (Handles BODMAS too).
Example:
ScriptEngineManager mgr = new.ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2/3*45";
System.out.println(engine.eval(foo));
Outputs: 70
Include the following imports , if the IDE doesn't suggest them :
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
Check the documentation here ScriptEngine
I hope it helps.
The solution can be achieved by using the shunting yard algorithm. We start by creating an infix notation of the equation then follows the postfix notation. Here is a description of the algorithm https://en.wikipedia.org/wiki/Shunting_yard_algorithm. This solution solves for any nested number of brackets on the string expression.
public static double evaluate(String exp) {
char[] tokens = exp.toCharArray();
Queue<Object> values = new LinkedList<>();
// Stack for Operators: 'ops'
Stack<Character> ops = new Stack<Character>();
for (int i = 0; i < tokens.length; i++) {
//infix
// Current token is a whitespace, skip it
if (tokens[i] == ' ') {
continue;
}
// Current token is a number, push it to stack for numbers
else if (tokens[i] >= '0' && tokens[i] <= '9') {
StringBuffer sbuf = new StringBuffer();
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') {
sbuf.append(tokens[i]);
if ((i+1)<tokens.length &&tokens[i + 1] >= '0' && tokens[i + 1] <= '9') {
i++;
} else {
break;
}
}
values.add(Double.parseDouble(sbuf.toString()));
} else if (tokens[i] == '*' || tokens[i] == '-' || tokens[i] == '/' || tokens[i] == '+') {
if (ops.isEmpty()) {
ops.push(tokens[i]);
continue;
}
char op1 = ops.peek();
boolean hasHighPrecedence = hasPrecedence(op1, tokens[i]);
if (hasHighPrecedence) {
char op = ops.pop();
values.add(op);
ops.push(tokens[i]);
} else {
ops.push(tokens[i]);
}
} else if (tokens[i] == '(') {
ops.push(tokens[i]);
} else if (tokens[i] == ')') {
while (ops.peek() != '(') {
values.add(ops.pop());
}
ops.pop();
}
}
while (!ops.isEmpty()) {
values.add(ops.pop());
}
//post fix
Stack<Double> numStack = new Stack<>();
while (!values.isEmpty()) {
Object val = values.poll();
if (val instanceof Character) {
char v = (Character) val;
if (v == '*' || v == '-' || v == '/' || v == '+') {
double num2, num1;
num1 = numStack.pop();
num2 = numStack.pop();
double ans = applyOp(v, num1, num2);
numStack.push(ans);
}
} else {
double num = (double) val;
numStack.push(num);
}
}
return numStack.pop();
}
public static double applyOp(char op, double b, double a) {
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new
IllegalArgumentException("Cannot divide by zero");
return a / b;
}
return 0;
}
public static boolean hasPrecedence(char op1, char op2) {
if (op1 == '*' && op2 == '/') {
return false;
} else if (op1 == '/' && op2 == '*') {
return true;
} else if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) {
return true;
} else if (op1 == '+' && op2 == '-') {
return true;
} else {
return false;
}
}
"BODMAS" is a not very operational rule. Especially addition and subtraction have the same precedence and are calculated from left to right 1-2+3-4+5 = (((1-2)+3)-4)+5.
The rule is for a nested loop.
Loop
replaceAll ( number ) --> number
replaceAll number `[*/]' number --> number op number
replaceAll number `[+-]' number --> number op number
Until nothing is replaced.
This ensures that 3-4/26+5 -2-> 3-26+5 -2-> 3-12+5 -3-> -9+5 -3-> -4
Related
This is my code:
import java.util.*;
public class TruthTable {
public static boolean evaluateExpression(String expression, boolean p, boolean q) {
Stack<Boolean> stack = new Stack<>();
Stack<Character> opStack = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == 'p') {
stack.push(p);
} else if (c == 'q') {
stack.push(q);
} else if (c == '¬') {
boolean b = stack.pop();
stack.push(!b);
} else if (c == '∧') {
// Check if the next character is a ¬ character.
if (i + 1 < expression.length() && expression.charAt(i + 1) == '¬') {
// If the next character is a ¬ character, pop the top of the stack and negate it,
// then push the conjunction of the negated value and the value of q.
boolean b = stack.pop();
stack.push(!(b && q));
// Increment the index to skip the ¬ character.
i++;
} else {
// If the next character is not a ¬ character, simply push the conjunction of the
// value of p and the value of q.
stack.push(stack.pop() && q);
}
} else if (c == '∨' || c == '→' || c == '↔' || c == '⊕' || c == '⊼' || c == '⊽') {
while (!opStack.isEmpty() && getPrecedence(c) <= getPrecedence(opStack.peek())) {
char op = opStack.pop();
applyOperator(op, stack);
}
opStack.push(c);
}
}
while (!opStack.isEmpty()) {
char op = opStack.pop();
applyOperator(op, stack);
}
return stack.pop();
}
private static void applyOperator(char op, Stack<Boolean> stack) {
boolean b1 = stack.pop();
boolean b2 = stack.pop();
switch (op) {
case '∧':
stack.push(b1 && b2);
break;
case '∨':
stack.push(b1 || b2);
break;
case '→':
stack.push(!b1 || b2);
break;
case '↔':
stack.push(b1 == b2);
break;
case '⊕':
stack.push(b1 != b2);
break;
case '⊼':
stack.push((b1 && b2) || (!b1 && b2) || (b1 && !b2));
break;
case '⊽':
stack.push(b1 && b2 && stack.pop());
break;
case '¬':
stack.push(!b1);
break;
}
}
private static int getPrecedence(char op) {
switch (op) {
case '¬':
return 3;
case '∧':
return 2;
case '∨':
return 1;
case '→':
return 0;
case '↔':
return 0;
case '⊕':
return 1;
case '⊼':
if (op == '∨' || op == '→' || op == '↔' || op == '⊕') {
return 2;
} else {
return 3;
}
case '⊽':
return 2;
default:
return -1;
}
}
public static void main(String[] args) {
String expression = "pq¬∨pq∧→";
System.out.println("p\tq\t(" + expression + ")");
for (boolean p : new boolean[]{true, false}) {
for (boolean q : new boolean[]{true, false}) {
System.out.println(p + "\t" + q + "\t" + evaluateExpression(expression, p, q));
}
}
}
}
The expected result is true false true false but it prints out false true false true and ive been trying to figure out how to fix it but I just cant. Will appreciate any help
Ive tried changing the precedence but it only produced the output True true true true
I don't expect many people will be able to help you, especially if you cannot see the logic error and you are the author!
When writing code like this, your best option is to write Unit Tests. Test parts of the implementation first and then give your algorithm expressions bit by bit and work up to more complex cases.
Note that your use of private static methods may frustrate your ability to test parts or mock out parts of the code. Go find an article about Unit Testing and Dependency Injection; it will be worthwhile your investment.
I tried to Evaluate Mathematical Expressions in Java with the following code:
public double applyOp(char op,double b,double a)
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
return 0;
}
public boolean hasPrecedence(char op1,char op2)
{
return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');
}
public double evaluate(String input) {
Stack<Double> values = new Stack<>();
Stack<Character> ops = new Stack<>();
int stringIndex = 0;
while (stringIndex < input.length())
{
StringBuilder multiDigitsNumber = new StringBuilder();
// If the input is number put to stack values
if (input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9')
{
while (stringIndex < input.length() && input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9')
{
multiDigitsNumber.append(input.charAt(stringIndex++));
}
values.push(Double.parseDouble(multiDigitsNumber.toString()));
}
// If the input is operator put to stack ops
else
{
while (!ops.empty() && hasPrecedence(input.charAt(stringIndex),ops.peek()))
{
values.push(applyOp(ops.pop(),values.pop(),values.pop()));
}
ops.push(input.charAt(stringIndex++));
}
}
// Execute remain operator in stack values
while (!ops.empty()) {
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
}
// The final number in stack value is result
return values.pop();
}
Input example:
12+24*2-30/5.....
The code above works fine but I wonder are there any way to replace
while (stringIndex < input.length() && input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9')
{
multiDigitsNumber.append(input.charAt(stringIndex++));
}
with something else so I don't have to use nested while loop in this situation. The goal is to catch number in string until it reach an operator
Thanks in advance
You can use Regex like this.
if (input.charAt(stringIndex) >= '0' && input.charAt(stringIndex) <= '9')
{
String number = input.substring(stringIndex).replaceAll("^(\\d+).*", "$1");
values.push(Double.parseDouble(number));
stringIndex += number.length();
}
I'm trying to write a calc program that finds the infix. In addition the user will input numbers for the x variable and the program will solve it. My program works but it only solves it the first time. The following times it gives the same answer as the first time.
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
class Stack {
char a[] = new char[100];
int top = -1;
void push(char c) {
try {
a[++top] = c;
} catch (StringIndexOutOfBoundsException e) {
System.out.println("Stack full , no room to push , size=100");
System.exit(0);
}
}
char pop() {
return a[top--];
}
boolean isEmpty() {
return (top == -1) ? true : false;
}
char peek() {
return a[top];
}
}
public class intopost {
static Stack operators = new Stack();
public static void main(String argv[]) throws IOException {
String infix;
// create an input stream object
BufferedReader keyboard = new BufferedReader(new InputStreamReader(
System.in));
// get input from user
System.out.print("\nEnter the algebraic expression in infix: ");
infix = keyboard.readLine();
String postFx = toPostfix(infix);
// output as postfix
System.out.println("The expression in postfix is:" + postFx);
if (postFx.contains("x")) {
String line = "";
do {
System.out.println("Enter value of X : ");
line = keyboard.readLine();
if (!"q".equalsIgnoreCase(line)) {
postFx = postFx.replaceAll("x", line);
System.out.println("Answer to expression : "
+ EvaluateString.evaluate(postFx));
}
} while (!line.equals("q"));
} else {
System.out.println("Answer to expression : "
+ EvaluateString.evaluate(postFx));
}
}
private static String toPostfix(String infix)
// converts an infix expression to postfix
{
char symbol;
String postfix = "";
for (int i = 0; i < infix.length(); ++i)
// while there is input to be read
{
symbol = infix.charAt(i);
// if it's an operand, add it to the string
if (symbol != ' ') {
if (Character.isLetter(symbol) || Character.isDigit(symbol))
postfix = postfix + " " + symbol;
else if (symbol == '(')
// push (
{
operators.push(symbol);
} else if (symbol == ')')
// push everything back to (
{
while (operators.peek() != '(') {
postfix = postfix + " " + operators.pop();
}
operators.pop(); // remove '('
} else
// print operators occurring before it that have greater
// precedence
{
while (!operators.isEmpty() && !(operators.peek() == '(')
&& prec(symbol) <= prec(operators.peek()))
postfix = postfix + " " + operators.pop();
operators.push(symbol);
}
}
}
while (!operators.isEmpty())
postfix = postfix + " " + operators.pop();
return postfix.trim();
}
static int prec(char x) {
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/' || x == '%')
return 2;
return 0;
}
}
class EvaluateString {
public static int evaluate(String expression) {
char[] tokens = expression.toCharArray();
// Stack for numbers: 'values'
LinkedList<Integer> values = new LinkedList<Integer>();
// Stack for Operators: 'ops'
LinkedList<Character> ops = new LinkedList<Character>();
for (int i = 0; i < tokens.length; i++) {
// Current token is a whitespace, skip it
if (tokens[i] == ' ')
continue;
// Current token is a number, push it to stack for numbers
if (tokens[i] >= '0' && tokens[i] <= '9') {
StringBuffer sbuf = new StringBuffer();
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0'
&& tokens[i] <= '9')
sbuf.append(tokens[i++]);
values.push(Integer.parseInt(sbuf.toString()));
}
// Current token is an opening brace, push it to 'ops'
else if (tokens[i] == '(')
ops.push(tokens[i]);
// Closing brace encountered, solve entire brace
else if (tokens[i] == ')') {
while (ops.peek() != '(')
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
ops.pop();
}
// Current token is an operator.
else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*'
|| tokens[i] == '/') {
// While top of 'ops' has same or greater precedence to current
// token, which is an operator. Apply operator on top of 'ops'
// to top two elements in values stack
while (!ops.isEmpty() && hasPrecedence(tokens[i], ops.peek()))
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been parsed at this point, apply remaining
// ops to remaining values
while (!ops.isEmpty())
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Top of 'values' contains result, return it
return values.pop();
}
// Returns true if 'op2' has higher or same precedence as 'op1',
// otherwise returns false.
public static boolean hasPrecedence(char op1, char op2) {
if (op2 == '(' || op2 == ')')
return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
return false;
else
return true;
}
// A utility method to apply an operator 'op' on operands 'a'
// and 'b'. Return the result.
public static int applyOp(char op, int b, int a) {
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}
There is a mistake inside while loop in main method. See snippet below.
postFx = postFx.replaceAll("x", line);
System.out.println("Answer to expression : "
+ EvaluateString.evaluate(postFx));
Here postFx = postFx.replaceAll("x", line); you lost reference to postfix form that contains variable x. Subsequent calls of replaceAll doesn't have any effect. So expression with first entered value is evaluated.
You can easily fix it by replacing code above with
System.out.println("Answer to expression : "
+ EvaluateString.evaluate(postFx.replaceAll("x", line)));
Currently, I am working on a method to convert from Infix notation to Postfix notation. I've been writing multiple JUnit tests and regular things like 2*2 or 1+3 are working but anything with parentheses is not working.
For example, (5+2) * (3*5)
During debugging, I always see that my postFixResult string always has the first parentheses added on to the so the beginning of the string is 5 ( 2. I'm not sure what I am doing wrong as I have followed multiple posts around here regarding this problem.
public static String infixToPostFix(String message) throws PostFixException {
MyStack<Character> operatorStack = new MyStack<Character>();
String postFixResult = "";
Scanner tokenizer = new Scanner(message);
while (tokenizer.hasNext()) {
if (tokenizer.hasNextInt()) {
postFixResult += " " + tokenizer.nextInt();
} else {
String value = tokenizer.next();
Operator op = new Operator(value.charAt(0));
char c = value.charAt(0);
String operators = "*/-+()";
if (!isOperator(c)) {
//If the character is not an operator or a left parentheses.
throw new PostFixException("Invalid Operator");
} else {
if (c == ')') {
while (!operatorStack.isEmpty() && operatorStack.peek() != '(') {
postFixResult += " " + operatorStack.pop();
}
if (!operatorStack.isEmpty()) {
operatorStack.pop();
}
}
else {
if (!operatorStack.isEmpty() && !isLowerPrecedence(c, operatorStack.peek())) {
operatorStack.push(c);
}
else {
while (!operatorStack.isEmpty() && isLowerPrecedence(c, operatorStack.peek())) {
Character pop = operatorStack.pop();
if (c != '(') {
postFixResult += " " + pop;
} else {
c = pop;
}
}
operatorStack.push(c);
}
}
}
}
}
while (!operatorStack.isEmpty()) {
postFixResult += " " + operatorStack.pop();
}
return postFixResult;
}
/**
* Method that returns true if c is an operator.
* #param c
* #return
*/
private static boolean isOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
|| c == '(' || c == ')';
}
/**
* Determines whether or not the character is actually a number.
* #param c
* #return true if character is number false, otherwise.
*/
private boolean isNumber(char c){
return Character.isDigit(c);
}
/**
* A method to determine precedence of operators.
* #param c1 Operator 1
* #param c2 Operator 2
* #return true if c2 is lower precedence than c1.
*/
private static boolean isLowerPrecedence(char c1, char c2)
{
switch (c1)
{
case '+':
case '-':
return !(c2 == '+' || c2 == '-');
case '*':
case '/':
return c2 == '^' || c2 == '(';
case '^':
return c2 == '(';
case '(':
return true;
default:
//means that the character must have passed through as something else.
return false;
}
}
Parentheses are not needed in a postfix expression, that's the beauty of it. '(' and ')' should not go into your end result(postfix) and should be discarded when popped from the stack itself.
This is my class:
import java.io.*;
import java.util.*;
import java.lang.*;
import java.util.Scanner;
import java.util.List;
import java.util.Stack;
/**
*
* #author rtibbetts268
*/
public class InfixToPostfix
{
/**
* Operators in reverse order of precedence.
*/
private static final String operators = "_-+/*";
private static final String operands = "0123456789x";
public String xToValue(String postfixExpr, String x)
{
char[] chars = postfixExpr.toCharArray();
StringBuilder newPostfixExpr = new StringBuilder();
for (char c : chars)
{
if (c == 'x')
{
newPostfixExpr.append(x);
}
else
{
newPostfixExpr.append(c);
}
}
return newPostfixExpr.toString();
}
public String convert2Postfix(String infixExpr)
{
char[] chars = infixExpr.toCharArray();
StringBuilder in = new StringBuilder(infixExpr.length());
for (int i : chars)
{
if (infixExpr.charAt(i) == '-')
{
if (isOperand(infixExpr.charAt(i+1)))
{
if (i != infixExpr.length())
{
if (isOperator(infixExpr.charAt(i-1)))
in.append('_');
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
chars = in.toString().toCharArray();
Stack<Character> stack = new Stack<Character>();
StringBuilder out = new StringBuilder(in.toString().length());
for (char c : chars)
{
if (isOperator(c))
{
while (!stack.isEmpty() && stack.peek() != '(')
{
if (operatorGreaterOrEqual(stack.peek(), c))
{
out.append(stack.pop());
}
else
{
break;
}
}
stack.push(c);
}
else if (c == '(')
{
stack.push(c);
}
else if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
out.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else if (isOperand(c))
{
out.append(c);
}
}
while (!stack.empty())
{
out.append(stack.pop());
}
return out.toString();
}
public int evaluatePostfix(String postfixExpr)
{
char[] chars = postfixExpr.toCharArray();
Stack<Integer> stack = new Stack<Integer>();
for (char c : chars)
{
if (isOperand(c))
{
stack.push(c - '0'); // convert char to int val
}
else if (isOperator(c))
{
int op1 = stack.pop();
int op2 = stack.pop();
int result;
switch (c) {
case '*':
result = op1 * op2;
stack.push(result);
break;
case '/':
result = op2 / op1;
stack.push(result);
break;
case '+':
result = op1 + op2;
stack.push(result);
break;
case '-':
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}
private int getPrecedence(char operator)
{
int ret = 0;
if (operator == '_')
{
ret = 0;
}
if (operator == '-' || operator == '+')
{
ret = 1;
}
else if (operator == '*' || operator == '/')
{
ret = 2;
}
return ret;
}
private boolean operatorGreaterOrEqual(char op1, char op2)
{
return getPrecedence(op1) >= getPrecedence(op2);
}
private boolean isOperator(char val)
{
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val)
{
return operands.indexOf(val) >= 0;
}
}
In it I change infix expressions to postfix expressions with the method convert2Postfix()
There is a small section in it at the very beginning where I am rewriting the string input with all negative numbers having a '_' infront of them instead of a "-". It doesn't work.
ex: change -4 to _4
What do I need to do to make this work?
You have a number of errors here, here is the first one:
for (int i : chars)
chars is converted to the corresponding int. For example if chars contains one single character 'A':
char [] chars = new char[1];
chars[0] = 'A';
for(int i: chars){
System.out.println(i); //You will have a '65' here
}
What you really mean is probably:
for (int i=0;i<chars.length;++i)
This is also wrong:
if (isOperator(infixExpr.charAt(i-1)))
It should be :
if (isOperator(infixExpr.charAt(i)))
Then there is a problem in the way you put and remove elements in the stack.
After all this changes you should also do this:
return out.reverse().toString();
instead of :
return out.toString();
Here is what I ended up with: http://pastebin.com/2TLqPUsH
(Change the name of the classes of course)