四则运算笔试题
方便日后回忆,立个flag。如果有好的解法,望各位不吝赐教。我这里采用的是将中缀表达式转换成后缀表达式。同时,要注意 负数 和 多位数的标记。
参考博客:https://www.cnblogs.com/dragondove/p/6445850.html
import java.util.Scanner;
import java.util.Stack;
/**
* 四则运算
* https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e?tpId=37&tqId=21273&tPage=3&rp=&ru=/ta/huawei&qru=/ta/huawei/question-ranking
* Created by superhero on 2018/3/16.
*/
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String strExpression = null;
while (scanner.hasNext()){
strExpression = scanner.nextLine();
strExpression = strExpression.replaceAll("[\\[{]","(");
strExpression = strExpression.replaceAll("[]}]",")");
StringBuilder str = new StringBuilder();
for(int i = 0;i < strExpression.length();i++){
char var = strExpression.charAt(i);
if(i == 0 && var == '-'){ //负号
str.append('0');
str.append(var);
}
else if(var == '-' && strExpression.charAt(i-1) == '(') {
str.append("(0");
str.append(var); //将负数用括号包起来
i++;
while (strExpression.charAt(i) >= '0' && strExpression.charAt(i) <= '9')
str.append(strExpression.charAt(i++));
str.append(')');
str.append(strExpression.charAt(i));
}
else
str.append(var);
}
System.out.println(calculate(isPushStack(str.toString())));
}
}
/**
* 根据 后缀表达式 进行计算。
* 法则:
* 遇见数字就入栈,遇见符号,就与前两个数字进行运算。
*/
public static int calculate(String strExpression){
Stack<Integer> stack = new Stack<>();
for(int i = 0;i < strExpression.length();i++){
char var = strExpression.charAt(i);
if(var == '(') { //遇见数字
StringBuilder num = new StringBuilder();
i++;
while(strExpression.charAt(i) != ')'){
num.append(strExpression.charAt(i));
i++;
}
stack.push(Integer.parseInt(num.toString()));
}
else{
int count = 0;
int var2 = stack.pop();
int var1 = stack.pop();
if(var == '+'){
count = var1 + var2;
}
else if(var == '-'){
count = var1 - var2;
}
else if(var == '*')
count = var1 * var2;
else if(var == '/')
count = var1 / var2;
stack.push(count);
}
}
return stack.pop();
}
/**
* 将 中缀表达式 转换成 后缀表达式
* 法则:
* 1)如果遇到数字,我们就直接将其输出。
2)如果遇到非数字时,若栈为空或者该符号为左括号或者栈顶元素为括号,直接入栈。
3)如果遇到一个右括号,持续出栈并输出符号,直到栈顶元素为左括号,然后将左括号出栈(注意,左括号只出栈,不输出),右括号不入栈
4)如果遇到运算符号且栈非空,查看栈顶元素,如果栈顶元素的运算优先级大于或者等于该运算符号,则持续出栈,直到栈顶元素优先级小于该运算符。最后将该元素入栈
5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
*/
private static String isPushStack(String strExpression){
StringBuffer sb = new StringBuffer(); //保存转换后的后缀表达式
Stack<Character> stack = new Stack<>();
for(int i = 0;i < strExpression.length();i++){
char var = strExpression.charAt(i);
if(var >= '0' && var <= '9') { //如果该符号为数字,直接输出
sb.append('('); //将数字用()包起来。以判断该数是个位数还是多位数
while ( strExpression.charAt(i) >= '0' && strExpression.charAt(i) <= '9') {
sb.append(strExpression.charAt(i));
if( i < strExpression.length() - 1)
i++;
else
break;
}
sb.append(')');
var = strExpression.charAt(i);
}
if((stack.isEmpty() && (var < '0' || var > '9')) || var == '(' || stack.peek() == '(' || stack.peek() == ')') //如果栈为空、该符号为左括号、栈顶元素为括号,入栈
stack.push(var);
else if(var == ')' ){ //如果该符号为 右括号 。持续出栈并输出,直到栈顶元素为左括号,并出栈。
while (stack.peek() != '(')
sb.append(stack.pop());
stack.pop();
}
else if(!stack.isEmpty() && (var == '+' || var == '-' || var == '*' || var == '/')){ //栈非空,且为运算符
while (!stack.isEmpty() && isFrist(stack.peek(),var))
sb.append(stack.pop());
stack.push(var);
}
}
while (!stack.isEmpty()) //遍历结束,将栈中的元素全部输出
sb.append(stack.pop());
return sb.toString();
}
private static boolean isFrist(char var1,char var2){ //判断两个运算符的优先级,var1 大于等于 var2 返回 true
if(var1 == '*' || var1 == '/'){
return true;
}
else if(var1 == '+' || var1 == '-'){
if(var2 == '*' || var2 == '/')
return false;
else
return true;
}
else //指的是 var1 == '(' 的情况
return false;
}
}
#笔试题目#