我正在编写一个验证算术表达式正确形成的程序。 (例如:正确的表单"2 + (2-1)"
,不正确的表单")2+(2-1"
)
一旦验证,程序将计算结果。
目前,它可以轻松地计算括号中的任何内容。但是如果涉及括号(例如,"2 [ 3 + (1) ]"
)程序验证表达式是否正确,但无法计算结果。
以下是我关注的代码
void postfixExpression() {
stk.clear(); // Re-using the stack object
Scanner scan = new Scanner(expression);
char current;
// The algorithm for doing the conversion.... Follow the bullets
while (scan.hasNext()) {
String token = scan.next();
if (isNumber(token))
{
postfix = postfix + token + " ";
} else {
current = token.charAt(0);
if (isParentheses(current))
{
if (stk.empty() || current == Constants.LEFT_NORMAL) {
// push this element on the stack;
stk.push(new Character(current));
} else if (current == Constants.RIGHT_NORMAL) {
try {
Character ch = (Character) stk.pop();
char top = ch.charValue();
while (top != Constants.LEFT_NORMAL) {
postfix = postfix + top + " ";
ch = (Character) stk.pop();
top = ch.charValue();
}
} catch (EmptyStackException e) {
}
}
} else if (isOperator(current))//
{
if (stk.empty()) {
stk.push(new Character(current));
} else {
try {
char top = (Character) stk.peek();
boolean higher = hasHigherPrecedence(top, current);
while (top != Constants.LEFT_NORMAL && higher) {
postfix = postfix + stk.pop() + " ";
top = (Character) stk.peek();
}
stk.push(new Character(current));
} catch (EmptyStackException e) {
stk.push(new Character(current));
}
}
}// Bullet # 3 ends
}
} // Outer loop ends
try {
while (!stk.empty()) // Bullet # 4
{
postfix = postfix + stk.pop() + " ";
}
} catch (EmptyStackException e) {
}
}
我创建了两个方法:isBracket和isCurly。起初,我认为最合适的解决方案是以与isParentheses相同的方式包含这两种方法。像这样:
if (isParentheses(current))
{
if (stk.empty() || current == Constants.LEFT_NORMAL) {
// push this element on the stack;
stk.push(new Character(current));
} else if (current == Constants.RIGHT_NORMAL) {
try {
Character ch = (Character) stk.pop();
char top = ch.charValue();
while (top != Constants.LEFT_NORMAL) {
postfix = postfix + top + " ";
ch = (Character) stk.pop();
top = ch.charValue();
}
} catch (EmptyStackException e) {
}
}
if (isCurly(current))
{
if (stk.empty() || current == Constants.LEFT_CURLY) {
// push this element on the stack;
stk.push(new Character(current));
} else if (current == Constants.RIGHT_CURLY) {
try {
Character ch = (Character) stk.pop();
char top = ch.charValue();
while (top != Constants.LEFT_CURLY) {
postfix = postfix + top + " ";
ch = (Character) stk.pop();
top = ch.charValue();
}
} catch (EmptyStackException e) {
if (isBracket(current))
{
if (stk.empty() || current == Constants.LEFT_SQUARE) {
// push this element on the stack;
stk.push(new Character(current));
} else if (current == Constants.RIGHT_SQUARE) {
try {
Character ch = (Character) stk.pop();
char top = ch.charValue();
while (top != Constants.LEFT_SQUACRE) {
postfix = postfix + top + " ";
ch = (Character) stk.pop();
top = ch.charValue();
}
} catch (EmptyStackException e) {
但该程序仍然不会考虑括号和括号(但它仍然可以正确读取括号。)
我没有按照我的理解正确使用这些方法,但我怎样才能正确使用它们?
答案 0 :(得分:0)
这是我想到的一个想法,采取不同的方法解决这个问题。
您可以将数字和括号分成两个不同的堆栈,以便更容易确保表达式正确形成。
在代码的开头,您可以声明两个堆栈变量:
Stack<Integer> numbers = new Stack<Integer>();
Stack<Character> operators = new Stack<Character>();
然后相应地推送运营商和号码。
这是我创建的一个非常快速的方法,它将演示使用两个Stack
对象的实现:
public double doCalculation(String input) throws DataFormatException {
if (input == null) {
return 0;
}
char[] characters = input.toCharArray();
for (char character: characters) {
try {
// tries to push the number onto the number stack
numbers.push(Integer.parseInt("" + character));
} catch (NumberFormatException e1) {
// if this is caught, this means the character is non-numerical
operators.push(character);
}
}
while (operators.size() > 0) {
int i = numbers.pop();
int j = numbers.pop();
char operator = operators.pop();
switch (operator) {
case '+':
numbers.push(j + i);
break;
case '-':
numbers.push(j - i);
break;
case '*':
numbers.push(j * i);
break;
case '/':
numbers.push(j / i);
break;
case '^':
numbers.push((int)(Math.pow(j, i)));
break;
default:
throw new DataFormatException();
}
}
return numbers.pop();
}
只是为了好玩:
如果在将非数字字符推入堆栈之前将此代码添加到catch
块,它将按操作顺序计算等式:
char top;
try {
top = operators.peek();
} catch (EmptyStackException e2) {
operators.push(character);
continue;
}
if (getValue(character) > getValue(top)) {
operators.push(character);
continue;
} else {
try {
while (!(getValue(character) > getValue(operators.peek()))) {
char operator;
operator = operators.pop();
int i = numbers.pop();
int j = numbers.pop();
switch (operator) {
case '+':
numbers.push(j + i);
break;
case '-':
numbers.push(j - i);
break;
case '*':
numbers.push(j * i);
break;
case '/':
numbers.push(j / i);
break;
case '^':
numbers.push((int)(Math.pow(j, i)));
break;
default:
throw new DataFormatException();
}
}
} catch (EmptyStackException e3) {
operators.push(character);
continue;
}
假设相应地定义了getValue()
方法:
public int getValue(char character)
throws DataFormatException {
switch (character) {
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
case '^':
return 3;
default:
throw new DataFormatException();
}
}