开心学算法的第6天
中缀表达式实现简易计算器
接上篇中缀计算器的实现,这篇实现后缀表达式(逆波兰表达式)实现计算器,以及中缀表达式转换为后缀表达式。
后缀表达式计算器的实现
后缀表达式:3 4 + 5 * 6 -
实现思路:
只需要一个栈用来存储数值,在遍历的过程中遇到字符时就需要将数栈出栈两个元素并调用上一篇所实现的compute计算函数计算的值并将结果入栈,在遍历完成之后将结果入栈依次类推,最后栈中只剩余一个元素并且打印结果。
//后缀
//从左向右依次入栈只存在一个数栈,如果遇到运算符则直接出栈两个元素,最后将计算结果入栈
public static void afterCalculator(stack<Integer> number,String expression){
String[] split = expression.split(" ");
//后缀表达还是只需要一个栈
for (int i = 0; i < split.length; i++) {
if (split[i].matches("\\d+")){
//匹配多位数
number.push(Integer.valueOf(split[i]));
}else {
//运算符
Character character = Character.valueOf(split[i].charAt(0));
//出两个数栈
int num1 = Integer.valueOf(number.pop());
int num2 = Integer.valueOf(number.pop());
int res = compute(num1, num2, character);
//将计算结果入栈
number.push(res);
}
}
System.out.println(number.pop());
}
中缀表达式转化为后缀表达式
实列:1+((2+3)*4)-5 ------------> 123+4*+5-
首先先将字符串转为字符型的集合
//将字符串转换为集合
private static List<String> strTransferList(String expression) {
//结果集
List<String> res = new ArrayList<>();
//用来处理多位数
int j = 0;
for (int i = 0; i < expression.length(); i++) {
if (Character.isDigit(expression.charAt(i))){
//用来处理多位数的缓存字符串
String str = String.valueOf(expression.charAt(i));
//表示的是数字
j = i + 1;
while (j < expression.length()){
if (Character.isDigit(expression.charAt(j))){
//表示的下一位字符仍然是数字,当前是一个多位数
str+=expression.charAt(j);
}else{
break;
}
j++;
}
//跳到下一个未遍历的
i = j - 1;
res.add(str);
}else {
//非数字
res.add(String.valueOf(expression.charAt(i)));
}
}
return res;
}
转换的过程
实现思路:
存在两个栈一个栈为结果栈res、还有一个中间栈stack,遍历字符集合,当遇到数字时直接入栈到res中,如果遇到‘(’括号直接入栈stack,当遇到‘)’,循环遍历stack中元素出栈并入栈到res,直至遇到’(’,最后出栈stack因为’('括号就要弃掉,如果遍历完以后发现stack不为空就要将其中的所有元素出栈并且入栈到res中,最后返回res,这样就可以办到中缀转换为后缀表达式。
//中缀表达式转换为后缀表达式 1+((2+3)*4)-5
public static void transfer(String expression){
List<String> list = strTransferList(expression);
stack<String> stack = new stack<>(10);
stack<String> res = new stack<>(10);
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
//开始判断数还是运算符
if (next.matches("\\d+")){
//表示的数
res.push(next);
} else if (next.equals("(")){
//不是数字
stack.push(next);
}else if (next.equals(")")){
//表示括号里面的东西全部入栈res
while (!stack.peek().equals("(")){
res.push(stack.pop());
}
//出栈(
stack.pop();
}else {
//符号栈不为null判断栈顶元素与当前运算符的优先级
while(!stack.isEmpty() && priority(stack.peek().charAt(0)) >= priority(next.charAt(0))){
res.push(stack.pop());
}
//当前操作符入栈
stack.push(next);
}
}
//将剩余的符号栈中的元素全部出栈并入栈到结果栈
while (!stack.isEmpty()){
res.push(stack.pop());
}
}
点个赞呗~~~