Java中可以利用双栈算法实现算术表达式求值,下面结合代码讲解简单和复杂两种情况
1、简单的算术表达式:(((3-1)*2)+3) 左括号全在左边时!
主要思想:
(1)利用两个栈,一个栈存储数字<栈顶到栈低依次是3123>,一个栈存储符号<栈顶到栈低依次是(((-)*)+)>
(2)符号栈弹出一个符号时,是括号时则忽略,否则数据栈弹出两个数据利用该符号进行计算,将计算结果在入栈
完整java代码如下:
import java.util.*;
public class StackCalculator {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner scan=new Scanner(System.in);
String string=scan.nextLine();
//将字符串转化成char类型数组
char[] c=new char[string.length()];
for(int i=0;i<string.length();i++){
c[i]=string.charAt(i);
}
Stack<Integer> stackint=new Stack<Integer>();
Stack<Character> stackchar=new Stack<Character>();
for(int i=(string.length()-1);i>=0;i--){
char ch=c[i];
if(ch>='0'&&ch<='9'){
//将char转成string,然后再讲string转成int<调用函数>
String s=ch+"";
stackint.push(Integer.parseInt(s));
}
if(ch>='('&&ch<='/'){
stackchar.push(ch);
}
}
char sign;
int a,b,data=0;
while(!stackchar.isEmpty()){
sign=stackchar.pop();
if(sign=='+'){
a=stackint.pop();
b=stackint.pop();
data=a+b;
stackint.push(data);
}
else if(sign=='-'){
a=stackint.pop();
b=stackint.pop();
data=a-b;
stackint.push(data);
}
else if(sign=='*'){
a=stackint.pop();
b=stackint.pop();
data=a*b;
stackint.push(data);
}
else if(sign=='/'){
a=stackint.pop();
b=stackint.pop();
if(b==0){
System.out.println("除数为0!");
System.exit(0);
}
data=a/b;
stackint.push(data);
}
}
data=stackint.pop();
System.out.println("Result="+data);
}
}
2、复杂的算术表达式:1+2*3+(4*5+6)*7,需要转化成后缀表达式:123+45*6+7*+
主要思想:
(1)当读到一个操作数时,立即将它放到输出中。操作符则不立即输出,放入栈中。遇到左圆括号也推入栈中
(2)如果遇到一个右括号,那么就将栈元素弹出,将符号写出直到遇到一个对应的左括号。但是这个左括号只被弹出,并不输出
(3)在读到操作符时,如果此时栈顶操作符优先性大于或等于此操作符,弹出栈顶操作符直到发现优先级更低的元素位置。除了处理)的时候,否则决不从栈中移走”(”。操作符中,+-优先级最低,()优先级最高
(4)如果读到输入的末尾,将栈元素弹出直到该栈变成空栈,将符号写到输出中
(5)上述四个原则便可将中缀表达式转化成后缀表达式,然后对后缀表达式进行处理得到最终结果<具体方式:利用一个数据栈,将后缀表达式的数据依次入栈,遇到符号时则将栈中弹出两个数据,然后利用该符号进行计算,将计算结果再入栈,从此往复>
完整Java代码如下:
import java.util.*;
public class StackCalculators {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner scan=new Scanner(System.in);
String string=scan.nextLine();
//将字符串转化成char类型数组
char[] carray=new char[string.length()];
for(int i=0;i<string.length();i++){
carray[i]=string.charAt(i);
}
//下面程序将中缀表达式转化成后缀表达式<重点>
char a,b;
int k=0;
char[] charray=new char[100];
Stack<Character> stackchar=new Stack<Character>();
Stack<Integer> stackint=new Stack<Integer>();
for(int i=0;i<string.length();i++){
a=carray[i];
if(a>='0'&&a<='9'){
charray[k++]=a;
}
else if(a=='*'||a=='/'||a=='('){
stackchar.push(a);
}
else if(a==')'){
b=stackchar.pop();
while(b!='('){
charray[k++]=b;
b=stackchar.pop();
}
}
else if(a=='+'||a=='-'){
if(stackchar.isEmpty())
stackchar.push(a);
else{
do{
b=stackchar.pop();
if(b=='(')
stackchar.push(b);
else
charray[k++]=b;
}while(!stackchar.isEmpty()&&b!='(');
stackchar.push(a);
}
}
}
while(!stackchar.isEmpty()){
b=stackchar.pop();
charray[k++]=b;
}
//利用后缀表达式和一个整型数据栈计算出结果
int data1,data2,data=0;
for(int i=0;i<k;i++){
char ch=charray[i];
if(ch>='0'&&ch<='9'){
//将char转成string,然后再讲string转成int<调用函数>
String str=ch+"";
stackint.push(Integer.parseInt(str));
}else{
data1=stackint.pop();
data2=stackint.pop();
if(ch=='+'){
data=data1+data2;
stackint.push(data);
}else if(ch=='-'){
data=data2-data1;
stackint.push(data);
}else if(ch=='*'){
data=data1*data2;
stackint.push(data);
}else if(ch=='/'){
if(data1==0){
System.out.println("除数为0!");
System.exit(0);
}else{
data=data2/data1;
stackint.push(data);
}
}
}
}
data=stackint.pop();
System.out.println("Result="+data);
}
}