infixToPostfix algorithm but without operation priority - java

If i have this string infix expression 2*4+3-15/2 and i want as output the postfix expression without considering the priority of the operations like so
2 4 * 3 + 15 - 2 /
What modifications do i need to in this code sample to "remove" that priority. I took this code from geeksforgeeks here https://www.geeksforgeeks.org/stack-set-2-infix-to-postfix/. I find it a little difficult to change to meet what i want. Where should i start? thanks.
the current code gives me this output : 24*3+152/-
private int Prec(String ch)
{
switch (ch)
{
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
case "^":
return 3;
}
return -1;
}
private boolean isNumeric(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
private String infixToPostfix(String infixExpression){
// initializing empty String for result
StringBuilder postfixExpression = new StringBuilder(new String(""));
String[] infixExp = infixExpression.split(" ");
// initializing empty stack
Stack<String> stack = new Stack<>();
for (String token : infixExp) {
System.out.println(token+" ");
// If the scanned character is an operand, add it to output.
if (isNumeric(token))
postfixExpression.append(token);
// If the scanned character is an '(', push it to the stack.
else if (token.equals("("))
stack.push(token);
// If the scanned character is an ')', pop and output from the stack
// until an '(' is encountered.
else if (token.equals(")")) {
while (!stack.isEmpty() && !stack.peek().equals("("))
postfixExpression.append(stack.pop());
if (!stack.isEmpty() && !stack.peek().equals("("))
return "Invalid Expression"; // invalid expression
else
stack.pop();
} else // an operator is encountered
{
while (!stack.isEmpty() && Prec(token) <= Prec(stack.peek())) {
if (stack.peek().equals("("))
return "Invalid Expression";
postfixExpression.append(stack.pop());
}
stack.push(token);
}
}
// pop all the operators from the stack
while (!stack.isEmpty()){
if(stack.peek().equals("("))
return "Invalid Expression";
postfixExpression.append(stack.pop());
}
System.out.println(postfixExpression);
return postfixExpression.toString();
}

It seems you just need to reverse the order of each pair formed by an operator and a number. You could do this using regular expressions and replaceAll:
String infix = "2*4+3-15/2";
String postfix = infix.replaceAll("([*+-/])([0-9]+)", " $2 $1");
System.out.println(postfix);
Output:
2 4 * 3 + 15 - 2 /

Related

Java, check if string is JSON Using Stacks

public class JsonValidator {
public static boolean isValidJSON(String jsonString) {
Stack<Character> stack = new Stack<>();
for (char c : jsonString.toCharArray()) {
switch (c) {
case '{':
stack.push(c);
break;
case '}':
if (stack.isEmpty()) {
return false;
}
Character last1 = stack.pop();
if (last1 != '{') {
return false;
}
break;
case '[':
stack.push(c);
break;
case ']':
if (stack.isEmpty()) {
return false;
}
Character last2 = stack.pop();
if (last2 != '[') {
return false;
}
break;
case '\"':
if (stack.isEmpty()) {
return false;
}
Character last3 = stack.peek();
if (last3 == '\"') {
stack.pop();
} else {
stack.push(c);
}
stack.push(c);
}
}
return stack.isEmpty();
}
assertTrue(JsonValidator.isValidJSON(""{""), "The brackets and quotes are balanced, making this a valid JSON string");
This is one of my test cases, its supposed to be valid JSON but it keeps giving me false
The problem with your checker is that when you check "{" you are pushing characters onto the stack that are never going to be popped. Hence, the stack is not empty.
Hint: look carefully at what is being pushed and popped when you process a string.
Also, your parser is not dealing with escapes in strings at all. And a { or } or [ or ] encountered within a JSON string should be treated as regular data.

Java Evaluating RPN using Shunting Yard Algorithm

I have the shunting yard algorithm that I found online:
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class ShuntingYardAlgorithm {
private enum Operator {
ADD(1), SUBTRACT(2), MULTIPLY(3), DIVIDE(4);
final int precedence;
Operator(int p) {
precedence = p;
}
}
private Map<String, Operator> operatorMap = new HashMap<String, Operator>() {/**
*
*/
private static final long serialVersionUID = 1L;
{
put("+", Operator.ADD);
put("-", Operator.SUBTRACT);
put("*", Operator.MULTIPLY);
put("/", Operator.DIVIDE);
}};
private boolean isHigherPrec(String op, String sub) {
return (operatorMap.containsKey(sub) &&
operatorMap.get(sub).precedence >= operatorMap.get(op).precedence);
}
public String shuntingYard(String infix) {
StringBuilder output = new StringBuilder();
Stack<String> stack = new Stack<String>();
for (String token : infix.split("")) {
//operator
if (operatorMap.containsKey(token)) {
while ( ! stack.isEmpty() && isHigherPrec(token, stack.peek())) {
output.append(stack.pop()).append(' ');
}
stack.push(token);
}
//left parenthesis
else if (token.equals("(")) {
stack.push(token);
}
//right parenthesis
else if (token.equals(")")) {
while ( ! stack.peek().equals("(")) {
output.append(stack.pop()).append(' ');
}
stack.pop();
}
//digit
else {
output.append(token).append(' ');
}
}
while ( ! stack.isEmpty()) {
output.append(stack.pop()).append(' ');
}
return output.toString();
}
}
And the evaluator:
private static int evalRPN(String[] tokens) {
int returnValue = 0;
String operators = "+-*/";
Stack<String> stack = new Stack<String>();
for (String t : tokens) {
if (!operators.contains(t)) {
stack.push(t);
} else {
int a = Integer.valueOf(stack.pop());
int b = Integer.valueOf(stack.pop());
switch (t) {
case "+":
stack.push(String.valueOf(a + b));
break;
case "-":
stack.push(String.valueOf(b - a));
break;
case "*":
stack.push(String.valueOf(a * b));
break;
case "/":
stack.push(String.valueOf(b / a));
break;
}
}
}
returnValue = Integer.valueOf(stack.pop());
return returnValue;
}
And they work good so far but I have a problem with the evaluation where the delimiter is split by "", which does not allow two digit numbers, such as 23, or above. What can you suggest that I can do to improve the evaluation method?
String output = new ShuntingYardAlgorithm().shuntingYard(algExp);
algExp = output.replaceAll(" ", "");
String[] outputArray = algExp.split("");
return evalRPN(outputArray);
Such as I input: 256+3
result: 2 5 6 3 +
Evaluation: 6 + 3 = 9, ignores 2 and 5
Your shuntingYard function is discarding the contents of output when an operator or a parenthesis is encountered.
You need to add checks for contents of output before processing the current character.
if (operatorMap.containsKey(token)) {
// TODO: Check output here first, and create a token as necessary
while ( ! stack.isEmpty() && isHigherPrec(token, stack.peek())) {
output.append(stack.pop()).append(' ');
}
stack.push(token);
}
//left parenthesis
else if (token.equals("(")) {
// TODO: Check output here first, and create a token as necessary
stack.push(token);
}
//right parenthesis
else if (token.equals(")")) {
// TODO: Check output here first, and create a token as necessary
while ( ! stack.peek().equals("(")) {
output.append(stack.pop()).append(' ');
}
stack.pop();
}
Also, splitting using the empty string is equivalent to just iterating the String one character at a time. Iterating infix using toCharArray() might be more readable
for (char c : infix.toCharArray())

Checking if parenthesis are balanced or not using Stack?

I have written a java code to test if an expression is balanced or not, that is, this program checks if the characters '(', '{' and '[' have a corresponding delimiter or not. However I am unable to get the required answer. There is something wrong and I am unable to figure it out and hence would need your help. Here is the code.
package z_Stack_InfixToPostfix;
import java.util.Stack;
public class Driver_InfixToPostfix {
public static void main(String[] args) {
String s="(a+b)";
System.out.println(checkBalance(s));
}
public static boolean checkBalance(String expression){
boolean isBalanced=true;
Stack<Character> myStack=new Stack<Character>();
int length=expression.length();
int i=0;
while(isBalanced && i<length){
switch(expression.charAt(i)){
case '(': case '{': case '[' :
myStack.push(expression.charAt(i));
break;
case ')': case '}': case ']':
if(myStack.isEmpty()){
isBalanced=false;
}
else{
char opendelimiter=myStack.pop();
if(opendelimiter!=expression.charAt(i)){
isBalanced=false;
}
}
break;
}
i++;
}
if(!myStack.isEmpty()){
isBalanced=false;
}
return isBalanced;
}
}
char opendelimiter=myStack.pop();
if(opendelimiter!=expression.charAt(i)){
isBalanced=false;
}
Here you should check
if(openedDeimilter == '('){
if(expression.charAt(i)!=')'){
isBalanced=false;
//break;
}
}else if(openedDeimilter == '['){
if(expression.charAt(i)!=']'){
isBalanced=false;
//break;
}
}else {
if(expression.charAt(i)!='}'){
isBalanced=false;
//break;
}
}
Also once isBalanced is set to false you can skip iterating the remaining string, if it suits you.
What about a different approach using only the length of your expression without each parentheses? This will let you not use the Stack class and should be more efficient for longer expression
public static boolean checkBalance(String expression) {
String[] parentheses = new String[]{"\\(|\\)","\\[|\\]","\\{|\\}"};
int length = expression.length();
for(int i=0; i<parentheses.length; i++) {
int newLength = expression.replaceAll(parentheses[i], "").length();
int diff = length - newLength;
if(diff % 2 != 0) {
return false;
}
}
return true;
}
The double backslash are used to escape each parentheses because they are special characters
This part is wrong:
if(opendelimiter!=expression.charAt(i)){
isBalanced=false;
}
You check if two chars are equal, but the correct check should match the 2 corresponding chars: [ - ], ( - ) and { - }
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char exp[1028];
char ext[1028];
int top = -1;
//-----------------------------------------------------------------------------
push(char x){
top++;
ext[top]=x;
}
//-----------------------------------------------------------------------------------------
void pop(){
top--;
}
//--------------------------------------------------------------------------------------
main()
{
int ans;
char in='{';
char it='[';
char ie='(';
char an;'}';
char at=']';
char ae=')';
printf("\nenter your expression\n");
gets(exp);
int j=strlen(exp);
int i;
for(i=0;i<=j;i++){
if(exp[i] == in || exp[i] == it || exp[i]==ie){
push(exp[i]);
}
if(exp[i] == an ||exp[i]== at || exp[i]==ae){
pop();
}
}
if(top == -1){
printf("\nexp is balanced\n");
}
else{
printf("\nexp is unbalanced");
}
}

Infix to Postfix Java Algorithm Issue

So I was assigned to create an method which takes in a string in infix notation as a parameter and returns a string in postfix notation.
My code seems to work for most examples I throw at it, but a few inputs cause wacky results.
public class Operations<T> {
public int value(char c){
switch(c){
case '(':
case ')':
return 3;
case '*':
case '/':
case '%':
return 2;
case '+':
case '-':
return 1;
default:
return 0;
}
}
public String infixToPostfix(String infix){
//Operator stack
myStack<Character> ops = new myStack<Character>();
//Postfix string
String postfix = "";
//Current char being read
char c;
//Marks if paranthesis are being passed in
boolean flag = false;
//Iterate through each character to find operators
for(int i=0; i<infix.length(); i++){
c = infix.charAt(i);
//Add operand to postfix and operator to stack
if(value(c)==0){
postfix+=c;
} else if(ops.isEmpty() || (value(c)>value(ops.getTop()) && c!=')') || c=='(') {
ops.push(c);
} else if(value(c)<value(ops.getTop()) && c!=')') {
if(ops.getTop()=='(' || flag) {
ops.push(c);
flag = true;
} else {
postfix+=ops.pop();
while(!ops.isEmpty() && value(c)<value(ops.getTop())) {
postfix+=ops.pop();
}
ops.push(c);
}
} else if(c==')') {
while(ops.getTop()!='('){
postfix+=ops.pop();
}
ops.pop();
flag = false;
} else {
postfix+=ops.pop();
ops.push(c);
}
}
while(!ops.isEmpty()){
postfix+=ops.pop();
}
return postfix;
}
}
for example, the equation:
- A * B + (C/D*7) – ( (A%C-8) / (H+F-D))
outputs:
ABCD/7+AC8-%HF+D-/-
while the correct answer is:
ABCD/7+AC%8-HF+D-/
What is causing the problem? Thanks

Issue with array based implementation of a stack (java)

I'm having trouble implementing a stack as an array in java. When I try to utilize the array, I get nullPointerExceptions. I know that the rest of my code works because I'm able to run the program using the linked list implementation of the stack I have created. The code is below:
Edit: The stack trace is
Exception in thread "main" java.lang.NullPointerException
at LispEvaluator.evaluate(LispEvaluator.java:238)
at LispEvaluator.fileLoader(LispEvaluator.java:67)
at Driver.main(Driver.java:16)
Here is the code for the lispEvaluator class
//code starts here
import java.util.*;
import java.io.*;
public class LispEvaluator {
// Current input Lisp expression
private String inputExpr;
private Scanner sc;
private StackList exprStack;
private StackList tempStack;
// default constructor
// set inputExpr to ""
// create stack objects
public LispEvaluator()
{
inputExpr = "";
}
// default constructor
// set inputExpr to inputExpression
// create stack objects
public LispEvaluator(String inputExpression)
{
inputExpr = inputExpression;
}
// set inputExpr to inputExpression
// clear stack objects
public void reset(String inputExpression)
{
inputExpr = inputExpression;
StackList exprStack=new StackList(50);
StackList tempStack=new StackList(50);
}
private boolean checkifNumber() {
return false;
}
public void fileLoader(String mode,String file){
//Validate the user entered mode
if(mode.equals("0")){
exprStack=new StackList(50);
tempStack=new StackList(50);}
else{
ArrayStack exprStack=new ArrayStack(50);
ArrayStack tempStack=new ArrayStack(50);
}
try{
//Try to read the array from file
sc = new Scanner(new File(file));
while (sc.hasNextLine()) {
double result=0;
inputExpr=sc.nextLine();
reset(inputExpr);
result=evaluate();
System.out.println(result);
}
}
catch (FileNotFoundException e){
System.out.println("Cannot find requested input file");
}
catch(IOException io){
System.out.println("General file io error occured. Try again");
}
}
// This function evaluate current operator with its operands
// See complete algorithm in evaluate()
//
// Main Steps:
// Pop operands from expressionStack and push them onto
// tempStack until you find an operator
// Apply the operator to the operands on tempStack
// Push the result into expressionStack
//
private double add() {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp + op2;}
return temp;
}
private double multiply() {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp * op2;}
return temp;
}
private double subtract() {
if (tempStack.size() == 1) {
double temp = -1*(Double) tempStack.pop();
return temp;
} else {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp - op2;}
return temp;
}
}
private double divide() {
double temp;
if (tempStack.size() == 1) {
temp = 1 / (Double) tempStack.pop();
return temp;
}
else if (tempStack.size() >=1) {
double op1 = (Double) tempStack.pop();
temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp / op2;}
return temp;
}
return 0;
}
private void evaluateCurrentOperation()
{
while( exprStack.top().getClass().getName().equals("java.lang.Double") ) {
tempStack.push( (Double)exprStack.pop() );
}
Character operator = (Character)exprStack.pop();
Double result = null;
switch( operator ) {
case '+':
result = add();
break;
case '*':
result = multiply();
break;
case '-':
result = subtract();
break;
case '/':
result = divide();
break;
}
exprStack.push( result );
}
/**
* This function evaluates Lisp expression in inputExpr
* It return result of the expression
*
* The algorithm:
*
* Step 1 Scan the tokens in the expression string.
* Step 2 If you see an operand, push operand object onto the expressionStack
* Step 3 If you see "(", next token should be an operator
* Step 4 If you see an operator, push operator object onto the expressionStack
* Step 5 If you see ")" // steps in evaluateCurrentOperation() :
* Step 6 Pop operands and push them onto tempStack
* until you find an operator
* Step 7 Apply the operator to the operands on tempStack
* Step 8 Push the result into expressionStack
* Step 9 If you run out of tokens, the value on the top of expressionStack is
* is the result of the expression.
*/
public double evaluate()
{
// only outline is given...
// you need to add statements
// you may delete or modify any statements in this method
// use scanner to tokenize inputExpr
Scanner inputExprScanner = new Scanner(inputExpr);
// Use zero or more white space as delimiter,
// which breaks the string into single character tokens
inputExprScanner = inputExprScanner.useDelimiter("\\s*");
// Step 1: Scan the tokens in the string.
while (inputExprScanner.hasNext())
{
// Step 2: If you see an operand, push operand object onto the expressionStack
if (inputExprScanner.hasNextInt())
{
// This force scanner to grab all of the digits
// Otherwise, it will just get one char
String dataString = inputExprScanner.findInLine("\\d+");
exprStack.push(new Double(dataString));
// more ...
}
else
{
// Get next token, only one char in string token
String aToken = inputExprScanner.next();
char item = aToken.charAt(0);
String nextToken;
char nextItem;
switch (item)
{
// Step 3: If you see "(", next token should be an operator
case '(':
nextToken = inputExprScanner.next();
nextItem = nextToken.charAt(0);
// Step 4: If you see an operator, push operator object onto the expressionStack
if (nextItem == '+') {
exprStack.push(nextItem);
} else if (nextItem == '-') {
exprStack.push(nextItem);
} else if (nextItem == '*') {
exprStack.push(nextItem);
}else if (nextItem == '/'){
exprStack.push(nextItem);
}
else {
exprStack.push(nextItem);
}
break;
// Step 5: If you see ")" // steps 6,7,8 in evaluateCurrentOperation()
case ')':
try {
evaluateCurrentOperation();
} catch (EmptyStackException e) {
break;
}
break;
default: // error
throw new RuntimeException(item + " is not a legal expression operator");
} // end switch
} // end else
} // end while
// Step 9: If you run out of tokens, the value on the top of expressionStack is
// is the result of the expression.
//
// return result
double result = (Double) exprStack.pop();
return result;
}
}
/*
// This static method is used by main() only
private static void evaluateExprt(String s, SimpleLispExpressionEvaluator expr)
{
Double result;
System.out.println("Expression " + s);
expr.reset(s);
result = expr.evaluate();
System.out.printf("Result %.2f\n", result);
System.out.println("-----------------------------");
}
// simple tests
public static void main (String args[])
{
SimpleLispExpressionEvaluator expr= new SimpleLispExpressionEvaluator();
String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))";
String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1)))";
String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1 )))";
String test4 = "(+ (/2))";
String test5 = "(+ (/2 3 0))";
String test6 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 3) (- 2 1 ))))";
evaluateExprt(test1, expr);
evaluateExprt(test2, expr);
evaluateExprt(test3, expr);
evaluateExprt(test4, expr);
evaluateExprt(test5, expr);
evaluateExprt(test6, expr);
} }
*/
And heres the Array Stack:
public class ArrayStack implements BoundedStack
{
private int top;
private Object stk[];
private int size;
private int capacity;
public ArrayStack(){
top=-1;
capacity=50;
stk=new Object[capacity];
}
public ArrayStack(int cap)
{
top=-1;
size=0;
capacity=cap;
stk=new Object[capacity];
}
public void push(Object item) throws FullStackException
{
if(isFull()){
throw new FullStackException("The stack is full. Cannot push more elements onto the stack");}
else
{
stk[++top]=item;
}
}
public Object pop() throws EmptyStackException
{
if(isEmpty()==true)
{
throw new EmptyStackException("The stack is empty. Cannot pop another element from the stack");
}
else{
Object e=stk[top];
stk [top]=null;
--top;
return e;
}
}
public Object top() throws EmptyStackException{
if(isEmpty()==true){
throw new EmptyStackException("The stack is empty. Thus, it has no top");
}
return stk[top];
}
public int size(){
return (top+1);
}
public boolean isFull(){
if (size()==capacity){
return true;}
return false;
}
public boolean isEmpty(){
if(size()==0){
return true;}
return false;
}
public int capacity(){
return capacity;
}
}
The most obvious reason for this is you have not initialized your array elements before using it.
If you are creating an array like: -
SomeClass[] arr = new SomeClass[5];
Then before using your array, you need to initialize each array elements like this: -
for (int i = 0; i < arr.length; i++) {
arr[i] = new SomeClass();
}
If the line causing the NullPointerException is the line
exprStack.push(nextItem);
then the problem is not in the stack class. The problem is that exprStack is null (probably because it has never been assigned anything before this line).
You're making the same error as the following one several times in your code:
public void reset(String inputExpression) {
inputExpr = inputExpression;
StackList exprStack=new StackList(50);
StackList tempStack=new StackList(50);
}
The two last lines are completely useless: they assign a new StackList to a local variable. So the stack is created, and is immediately eligible to garbage collection, since nothing references it except a local variable that goes out of scope.
Here's another place where it happens:
if (mode.equals("0")){
exprStack=new StackList(50);
tempStack=new StackList(50);
}
else {
ArrayStack exprStack=new ArrayStack(50);
ArrayStack tempStack=new ArrayStack(50);
}

Categories

Resources