我们平常的计算比如1+2是中缀表达式,即运算符在数与数之间,而后缀表达式则是运算符在数之后,即1 2 +,且遵循后进先出原则,
如 1 2 3 + *的结果是6,而不是9.
在1.中也提到了后进先出,自然想到最合适的数据结构便是堆栈。将输入的数逐一输入到堆栈中,遇到运算符时弹出堆栈最上方的两个数进行运算并将结果进栈,以此类推,当所有运算符结束堆栈中只剩下一个数的时候便是最终结果(如果不止一个数或者没有即输入出错)
首先输入的东西即有数字也有运算符,要保存结果则需要用到字符串和字符串数组,而java中没有直接输入字符串数组的方法,需要我们先输入字符串再将字符串转换成字符串数组。且需要约定你输入的东西中要有一个同一个的分隔符,举例子,一和十一,我们输入的时候都是按三次1,但是如果直接转换的话会是一一一,而我们要的是一和十一。在转换成字符数组时要将分隔符去掉。之后便是遍历字符数组,数字存入堆栈,运算符则取出堆栈最上面两个元素运算并把结果入栈。
split方法在java.lang.String包中,功能是将字符串去掉其中和入参相同的元素后并分割成字符数组。举个例子
String a="a+b+c+d";
String[] b=a.split("+");
这段代码结果是b成为字符数组,里面元素是(‘a‘,‘b‘,‘c,‘,‘d‘)
要注意的是1.[]不能省略2.如果用”.“或”|"作为分隔字符的话要加\,这样才能分隔开
import java.util.Stack;
需要输入这个才能使用,类中的几个方法,Type为我们定义的元素的类型
Type push(Type a) //把a入栈。 Type pop() //栈顶元素出栈并作为返回值 Type peek() //查看堆栈顶部的元素且不移除 boolean empty() //查看堆栈是否为空。 int search(Object a) //返回对象a在堆栈中的位置,注意基数从1开始。
使用时与正常创建对象一样,但是可以这样
Stacknum=new Stack<>();
这样代表num对象中都是double型
import java.util.Scanner;
import java.util.Stack;
import java.lang.String;
?
public class Main {
public static void main(String[] args) {
System.out.println("输入要计算的数字以及符号,每输入一个用空格分隔,整个长度在100个以内");
Main aaa=new Main();//这里创建对象是要用到下面的方法,其实也可以设成静态的
Scanner reader=new Scanner(System.in);
String input=reader.nextLine();//此处是输入
String[] a1=input.split(" ");//这里要注意,String后的[]不
// 能省,这是表示将输入的字符串转换成数组,且省了后split方法也会报错
//split方法是将字符串分割成字符数组,中间的参数是分隔符号,即遇到一次分隔符号划分一次
Stack<Double>num=new Stack<>();//java中的堆栈类
for(int i=0;i<a1.length;i++) {
if (!aaa.isOperate(a1[i])) {
num.push(Double.parseDouble(a1[i]));
//parseDouble(String a)表示返回字符串a代表的double值
} else {
double result = aaa.caculate(a1[i], num.pop(), num.pop());
num.push(result);
}
}
System.out.println(num.pop());
reader.close();
}
boolean isOperate(String a)
{
return a.equals("+")||a.equals("-")||a.equals("*")||a.equals("/");
}
double caculate(String a,double num1,double num2)
{
switch (a) {
case "+":
return num2 + num1;
case "-":
return num2-num1;
case "*":
return num2*num1;
case "/":
return num2/num1;
}
return -1;
}
}
代码部分有参考
原文:https://www.cnblogs.com/dadadaa/p/15038907.html