借助栈实现四则运算
四则运算
http://www.nowcoder.com/questionTerminal/9999764a61484d819056f807d2a91f1e
这里实现方法和表达式求值那篇文章一样,只是修改了输入校验规则和表达式转换方法,[ ],{ }本质上还是括号,优先级和( )一样,其他代码参见借助栈实现表达式求值
String pattern = "[^\\d|()()\\[\\]{}*+\\-/]"; /**
* 中缀表达式转后缀表达式(逆波兰表达式)
* @param expressions 表达式字符串数组
* @return 返回后缀表达式
*/
public static List<Object> infixToSuffix(String[] expressions){
if (null == expressions || expressions.length == 0) return null;
Stack<String> stack = new Stack<>();
StringBuilder builder = new StringBuilder();
List<Object> result = new ArrayList<>();
for (int i = 0; i < expressions.length; i++) {
if (i == 0 && !Character.isDigit(expressions[0].charAt(0)) &&
!expressions[0].equals("(") && !expressions[0].equals("(") &&
!expressions[0].equals("[") && !expressions[0].equals("{")){
builder.append(expressions[0]);
continue;
}
if (Character.isDigit(expressions[i].charAt(0))){
// 遇到数字,拼接起来,还原原数
builder.append(expressions[i]);
} else {
if (builder.length() != 0){
// 将还原后的数字存起来
result.add(Integer.parseInt(builder.toString()));
builder.delete(0, builder.length());
}
switch (expressions[i]){
case "+":
case "-":
if (expressions[i].equals("-") && i != 0 && (expressions[i - 1].equals("(") || expressions[i - 1].equals("(")
|| expressions[i - 1].equals("[") || expressions[i - 1].equals("{")))
builder.append(expressions[i]);
// +和-优先级相同且最低,当栈为空或栈顶元素为( 时直接入栈,注意,左括号只有遇到右括号才执行出栈
else if (stack.isEmpty() || stack.peek().equals("(") || stack.peek().equals("(")
|| stack.peek().equals("[") || stack.peek().equals("{"))
stack.push(expressions[i]);
else {
// 当栈不为空且栈顶元素不是左括号时,将栈元素依次输出,直到栈为空,再压入当前运算符
while (!stack.isEmpty() && !stack.peek().equals("(") && !stack.peek().equals("(")
&& !stack.peek().equals("[") && !stack.peek().equals("{"))
result.add(stack.pop());
stack.push(expressions[i]);
}
break;
case "*":
case "/":
// *和/优先级相同且大于+和-,小于括号,当栈为空或栈顶元素为( 时直接入栈,注意,左括号只有遇到右括号才执行出栈
if (stack.isEmpty() || stack.peek().equals("(") || stack.peek().equals("(")
|| stack.peek().equals("[") || stack.peek().equals("{"))
stack.push(expressions[i]);
else {
// 当栈不为空且栈顶元素不是左括号,同时栈顶元素优先级大于等于自己时,将栈元素依次输出,直到栈为空,再压入当前运算符
while (!stack.isEmpty() && !stack.peek().equals("+") && !stack.peek().equals("-")
&& !stack.peek().equals("(") && !stack.peek().equals("(")
&& !stack.peek().equals("[") && !stack.peek().equals("{"))
result.add(stack.pop());
stack.push(expressions[i]);
}
break;
case "(":
case "(":
case "[":
case "{":
// 遇到左括号直接入栈
stack.push(expressions[i]);
break;
case ")":
case ")":
case "]":
case "}":
// 遇到右括号,当栈不为空且栈顶元素不是左括号时,输出栈元素,直到栈为空或者遇到了左括号。注意这里不执行入栈操作
while (!stack.isEmpty() && !stack.peek().equals("(") && !stack.peek().equals("(")
&& !stack.peek().equals("[") && !stack.peek().equals("{"))
result.add(stack.pop());
// 因为遇到左括号而停止出栈时,需要将左括号出栈
if (!stack.isEmpty())
stack.pop();
break;
}
}
}
// 先清空builder
if (builder.length() != 0){
result.add(Integer.parseInt(builder.toString()));
builder.delete(0, builder.length());
}
// 最后一步,将栈中剩余元素全部输出
while (!stack.isEmpty())
result.add(stack.pop());
return result;
}