栈
1.用栈实现综合计算器
1 package Zhan; 2 3 import java.util.Scanner; 4 5 public class ComprehensiveCalculatorDemo { 6 public static void main(String[] args){ 7 MyStack ns=new MyStack(20);//存放数字的栈 8 MyStack os=new MyStack(20);//存放符号的栈 9 int num1=0; 10 int num2=0; 11 int index=0; 12 int res=0; 13 int oper; 14 char c=' '; 15 String multibitNumber=""; 16 System.out.println("输入表达式:"); 17 Scanner s=new Scanner(System.in); 18 String expersion=s.next(); 19 while(true){ 20 c=expersion.substring(index, index+1).charAt(0); 21 if(os.isOperator(c)){ 22 if(os.isEmpty()){ 23 os.push(c); 24 }else{ 25 if(os.priority(c)<os.priority(os.stack[os.top])){ 26 os.push(c); 27 }else{ 28 num1=ns.pop(); 29 num2=ns.pop(); 30 oper=os.pop(); 31 res=os.canculateResult(num1, num2, oper); 32 ns.push(res); 33 os.push(c); 34 35 } 36 } 37 }else{ 38 39 multibitNumber+=c; 40 if(index==expersion.length()-1){ 41 ns.push(Integer.parseInt(multibitNumber)); 42 }else{ 43 if(os.isOperator(expersion.substring(index+1, index+2).charAt(0))){ 44 ns.push(Integer.parseInt(multibitNumber)); 45 multibitNumber=""; 46 } 47 //ns.push(c-48);//进行字符转数字并入数字栈(注意字符"1"和数字"1"的区别!!!) 48 } 49 } 50 index++; 51 if(index>=expersion.length()){ 52 break; 53 } 54 } 55 56 while(true){ 57 if(os.isEmpty()){ 58 break; 59 }else{ 60 num1=ns.pop(); 61 num2=ns.pop(); 62 oper=os.pop(); 63 res=ns.canculateResult(num1, num2, oper); 64 ns.push(res); 65 } 66 67 } 68 int result=ns.pop(); 69 System.out.println(expersion+"="+result); 70 } 71 72 73 74 } 75 76 77 class MyStack{ 78 int maxSize; 79 int stack[]; 80 int top=-1; 81 82 public MyStack(int maxSize) { 83 this.maxSize = maxSize; 84 this.stack=new int[maxSize]; 85 } 86 87 //判断栈是否为空 88 public boolean isEmpty(){ 89 return top==-1; 90 } 91 92 93 94 //判断栈是否已满 95 public boolean isFull(){ 96 return top==maxSize-1; 97 } 98 99 //入栈 100 public void push(int data){ 101 if (isFull()){ 102 System.out.println("栈已满!!!"); 103 }else{ 104 top++; 105 stack[top]=data; 106 } 107 } 108 109 110 111 //出栈 112 public int pop(){ 113 if(isEmpty()){ 114 throw new RuntimeException("栈空!!!"); 115 }else{ 116 int temp=stack[top]; 117 top--; 118 return temp; 119 } 120 } 121 122 123 124 125 126 127 //显示栈内数据 128 public void show(){ 129 if(isEmpty()){ 130 throw new RuntimeException("栈空!!!"); 131 }else{ 132 for(int i=top;i>-1;i--){ 133 System.out.println("stack["+i+"]----->"+stack[i]); 134 } 135 } 136 } 137 138 139 140 141 142 143 //设定运算符号的优先级,优先级越高,所对应的数字越小,从1开始 144 public int priority(int operator){ 145 if(operator=='*'||operator=='/'){ 146 return 0; 147 }else if(operator=='+'||operator=='-'){ 148 return 1; 149 }else{ 150 return -1; 151 } 152 } 153 154 155 156 157 158 //判断是否为运算符 159 public boolean isOperator(int a){ 160 if(a=='*'||a=='/'||a=='+'||a=='-'){ 161 return true; 162 }else{ 163 return false; 164 } 165 } 166 167 168 169 170 171 //加、减、乘、除计算 172 public int canculateResult(int num1,int num2,int operator){ 173 int result=0; 174 switch(operator){ 175 case'*': 176 result=num2*num1; 177 break; 178 case'/': 179 result=num2/num1; 180 break; 181 case'+': 182 result=num2+num1; 183 break; 184 case'-': 185 result=num2-num1; 186 break; 187 default: 188 break; 189 } 190 191 return result; 192 193 } 194 195 }
结果:



存在问题:
最后一位数前的运算符号,将“+”当作"-",把“-”当作"+"
---------------------------------------------------------------------------------


这样反而没错
------------------------------------------------------------------------------------

打印每一步运算结果,可以发现,问题出现在最后while循环的计算里面,计算是从栈顶开始的,表现在运算式中是从后向前计算,这时,每一个运算符号后面的式子会先计算,相当于加了(),如果这个运算符号是+,那么后面加不加()的没什么影响,如果这个运算符号是-。那么后面加上()的话就会导致计算出的结果和原式不同。
修改:添加以下代码

完整代码:
1 package Zhan; 2 3 import java.util.Scanner; 4 5 public class ComprehensiveCalculatorDemo2 { 6 7 public static void main(String[] args){ 8 9 MyStack2 ns=new MyStack2(20); 10 MyStack2 os=new MyStack2(20); 11 System.out.println("输入表达式:"); 12 Scanner scanner=new Scanner(System.in); 13 String expersion=scanner.next(); 14 int num1=0; 15 int num2=0; 16 int res=0; 17 int oper; 18 int index=0; 19 char c=' '; 20 String multibitNumber=""; 21 22 //扫描表达式 23 while(true){ 24 c=expersion.substring(index, index+1).charAt(0);//一位一位截取字符串,并将截取后的内容准换为char类型 25 if(os.isOperator(c)){ 26 if(os.isEmpty()){ 27 os.push(c); 28 }else{ 29 if(os.priority(c)<=os.priority(os.stack[os.top])){ 30 num1=ns.pop(); 31 num2=ns.pop(); 32 oper=os.pop(); 33 res=os.canculateResult(num1, num2, oper); 34 ns.push(res); 35 os.push(c); 36 }else{ 37 os.push(c); 38 } 39 } 40 }else{ 41 multibitNumber+=c; 42 if(index>=expersion.length()-1){ 43 ns.push(Integer.parseInt(multibitNumber)); 44 }else{ 45 if(os.isOperator(expersion.subSequence(index+1, index+2).charAt(0))){//判断当前数字后面是否有数字,若有则进行拼接,再入栈,若没有则直接入栈 46 ns.push(Integer.parseInt(multibitNumber)); 47 multibitNumber=""; 48 } 49 } 50 } 51 index++; 52 if(index==expersion.length()){ 53 break; 54 } 55 56 } 57 58 59 //需要修改,使数栈和符号栈中的元素倒排 60 /* 61 while(true){ 62 if(os.isEmpty()){ 63 break; 64 }else{ 65 num1=ns.pop(); 66 num2=ns.pop(); 67 oper=os.pop(); 68 res=ns.canculateResult(num1, num2, oper); 69 ns.push(res); 70 } 71 72 } 73 74 */ 75 int a; 76 int b; 77 MyStack2 ns1=new MyStack2(20);//定义一个新的数栈,将原数栈中的元素压入栈,实现元素倒排 78 MyStack2 os1=new MyStack2(20);//定义一个新的符号栈,将原符号栈中的元素压入栈,实现元素倒排 79 80 while(ns.top!=-1){ 81 a=ns.pop(); 82 ns1.push(a); 83 84 } 85 86 87 while(os.top!=-1){ 88 b=os.pop(); 89 os1.push(b); 90 } 91 92 //对新的数栈和符号栈进行之前的操作 93 while(true){ 94 if(os1.isEmpty()){ 95 break; 96 }else{ 97 num1=ns1.pop(); 98 num2=ns1.pop(); 99 oper=os1.pop(); 100 res=ns1.canculateResult(num2, num1, oper);//注意参数顺序,与上面的canculateResult()方法中的参数顺序不同!!! 101 ns1.push(res); 102 } 103 } 104 105 int result=ns1.pop(); 106 System.out.println(expersion+"="+result); 107 108 109 110 } 111 } 112 113 114 115 116 class MyStack2{ 117 int maxSize; 118 int stack[]; 119 int top=-1; 120 121 public MyStack2(int maxSize) { 122 this.maxSize = maxSize; 123 this.stack=new int[maxSize]; 124 } 125 126 //判断栈是否为空 127 public boolean isEmpty(){ 128 return top==-1; 129 } 130 131 132 133 //判断栈是否已满 134 public boolean isFull(){ 135 return top==maxSize-1; 136 } 137 138 //入栈 139 public void push(int data){ 140 if (isFull()){ 141 System.out.println("栈已满!!!"); 142 }else{ 143 top++; 144 stack[top]=data; 145 } 146 } 147 148 149 150 //出栈 151 public int pop(){ 152 if(isEmpty()){ 153 throw new RuntimeException("栈空!!!"); 154 }else{ 155 int temp=stack[top]; 156 top--; 157 return temp; 158 } 159 } 160 161 162 163 164 165 166 //显示栈内数据 167 public void show(){ 168 if(isEmpty()){ 169 throw new RuntimeException("栈空!!!"); 170 }else{ 171 for(int i=top;i>-1;i--){ 172 System.out.println("stack["+i+"]----->"+stack[i]); 173 } 174 } 175 } 176 177 178 179 180 181 182 //设定运算符号的优先级,优先级越高,所对应的数字越大,从0开始 183 public int priority(int operator){ 184 if(operator=='*'||operator=='/'){ 185 return 1; 186 }else if(operator=='+'||operator=='-'){ 187 return 0; 188 }else{ 189 return -1; 190 } 191 } 192 193 194 195 196 197 //判断是否为运算符 198 public boolean isOperator(int oper){ 199 if(oper=='*'||oper=='/'||oper=='+'||oper=='-'){ 200 return true; 201 }else{ 202 return false; 203 } 204 } 205 206 207 208 209 210 //加、减、乘、除计算 211 public int canculateResult(int num1,int num2,int operator){ 212 int result=0; 213 switch(operator){ 214 case'*': 215 result=num2*num1; 216 break; 217 case'/': 218 result=num2/num1; 219 break; 220 case'+': 221 result=num2+num1; 222 break; 223 case'-': 224 result=num2-num1; 225 break; 226 default: 227 break; 228 } 229 return result; 230 231 } 232 233 234 235 }
运行结果:

正确!!!
2.中缀表达式转后缀表达式
2.1步骤


浙公网安备 33010602011771号