linkedlist remove bug
I have this homework assignment to make a calculator using a stack and converting infix to postfix. My infix to postfix method works fine. But the other method to evaluate it works for all cases except when multiples or divisors result in double digits. My calculator does not support double digit entries but supports evaluating double digits. Try inputing: 2+2*5/2, 2+5*4/2, and some others in similar format. The error is at line 151 on the second run when it goes to calculate the divide. This is what happens in the linkedlist: [2, 2, 5, *, 2, /, +] [2, 10, 2, /, +] [10, 2, +] -- error It should delete the / , 2 , and 10 hence the 3 removes statement. But when it does eval.remove(eval.get(i-1)) the 2 in front disappears and the 10 become the front node.
import java.util.Stack;
import java.util.LinkedList;
public class Calculator
{
Stack<Character> infix = new Stack<Character>();
StringBuilder postfix = new StringBuilder();
Stack<String> postfix_str = new Stack<String>();
String operators = "+-*/^";
String infix2postfix(String infix_str)
{
int i = 0;
boolean flag = true;
while (!infix_str.isEmpty())
{
if (infix_str.charAt(i) == '(')
{
infix.push(infix_str.charAt(i));
infix_str = infix_str.substring(i+1, infix_str.length());
}
else
{
if (Character.getNumericValue(infix_str.charAt(i)) >= 0 &&
Character.getNumericValue(infix_str.charAt(i)) <= 9)
{
postfix.append(infix_str.charAt(i));
postfix_str.push(String.valueOf(infix_str.charAt(i)));//added
infix_str = infix_str.substring(i+1, infix_str.length());
}
else //operator
{
if (!(infix_str.charAt(i) == ')'))
{
if (infix.empty() || infix.peek() == '(' || !(preced(infix_str.charAt(i), infix.peek())))
{
infix.push(infix_str.charAt(i));
infix_str = infix_str.substring(i+1, infix_str.length());
}
else
{
postfix_str.push(String.valueOf(infix.peek()));//added
postfix.append(infix.pop());
}
}
else
{
try
{
while (infix.peek() != '(')
{
postfix_str.push(String.valueOf(infix.peek()));//added
postfix.append(infix.pop());
}
infix.pop();
infix_str = infix_str.substring(i+1, infix_str.length());
}
catch(Exception EmptyStackException)
{
System.out.println("Unbalanced Parathesis");
break;
}
}
}
}
}
while (!infix.empty())
{
postfix_str.push(String.valueOf(infix.peek()));//added
postfix.append(infix.pop());
}
System.out.println(postfix);
System.out.println(postfix_str.toString());
return postfix.toString();
}
/**
*
* @param statement operator, top of stack
* @return true to pop
*/
boolean preced(char arg1, char arg2)//when to pop (true - pop)
{
String firstPreced = "^";
String secondPreced = "*/";
String thirdPreced = "+-";
//EQUALS TO
if ((thirdPreced.charAt(0) == arg1 || thirdPreced.charAt(1) == arg1)
&&
(thirdPreced.charAt(0) == arg2 || thirdPreced.charAt(1) == arg2))
{return true;}
if ((secondPreced.charAt(0) == arg1 || secondPreced.charAt(1) == arg1)
&&
(secondPreced.charAt(0) == arg2 || secondPreced.charAt(1) == arg2))
{return true;}
if (firstPreced.charAt(0) == arg1
&&
firstPreced.charAt(0) == arg2)
{return true;}
if ((thirdPreced.charAt(0) == arg1 || thirdPreced.charAt(1) == arg1)
开发者_运维知识库 &&
(secondPreced.charAt(0) == arg2 || secondPreced.charAt(1) == arg2))
{return true;}
if ((thirdPreced.charAt(0) == arg1 || thirdPreced.charAt(1) == arg1)
&&
(firstPreced.charAt(0) == arg2))
{return true;}
return false;
}
void evalPostfix(String postfix)//2+2*5/2
{
LinkedList<String> eval = new LinkedList<String>();
//[2, 2, 5, *, 2, /, +]
//[2, 10, 2, /, +]
//[2, 5, +] -- should be
//[10, 2, +] -- result
while (!postfix_str.empty())
{
eval.addFirst(postfix_str.pop());
}
int i = 0;
while (!(eval.size() == 1))
{
if (eval.get(i).equals("+") || eval.get(i).equals("-") || eval.get(i).equals("*") || eval.get(i).equals("/")
|| eval.get(i).equals("^"))
{
double total = 0;
if (eval.get(i).equals("+"))
{total = Double.valueOf(eval.get(i - 1)) + Double.valueOf(eval.get(i - 2));}
if (eval.get(i).equals("-"))
{total = Double.valueOf(eval.get(i - 1)) - Double.valueOf(eval.get(i - 2));}
if (eval.get(i).equals("*"))
{total = Double.valueOf(eval.get(i - 1)) * Double.valueOf(eval.get(i - 2));}
if (eval.get(i).equals("/"))
{total = Double.valueOf(eval.get(i - 2)) / Double.valueOf(eval.get(i - 1));}
if (eval.get(i).equals("^"))
{total = Double.valueOf(eval.get(i - 1)) ^ Double.valueOf(eval.get(i - 2));}
eval.remove(eval.get(i));
eval.remove(eval.get(i-1));//BUG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
eval.remove(eval.get(i-2));
i-=2;
String sum_str = Double.toString(total);
eval.add(i, sum_str);
total = 0;
}
else
{
i++;
}
}
System.out.println(eval.get(0));
}
}
import java.util.Scanner;
public class CalculatorTest
{
public static void main(String[] args)
{
while(true)
{
Calculator calc = new Calculator();
Scanner in = new Scanner(System.in);
System.out.println("Enter Calc");
String input = in.nextLine();
calc.infix2postfix(input);
calc.evalPostfix("");
}
}
}
It looks like you are using LinkedList#remove(Object)
to remove an item from the linked list. This method removes items by reference, so it searches for the item to delete. Since an item can appear in a linked list more than once, it sounds like it's finding the first instance of the item ("2"
) and deleting that one. [*]
Perhaps you could try using LinkedList#remove(int)
which removes an item by position. So:
eval.remove(i);
eval.remove(i-1);
eval.remove(i-2);
[*] I'm glossing over some details here, such as how two references to two strings can actually be the same item. This is probably due to string interning but I can't be sure without more detailed examination of your code.
精彩评论