中缀表达式
模拟简单的加减乘除计算
需要使用到两个栈协助操作,实现还是比较困难,但是搞懂了还是很nice的
保姆级别的注释,方便日后参考
1.定义要用到的方法
class ArrayStack1{ // 先创建一个栈
private int maxsize; // 栈的大小
private int[] stack; // 数组模拟栈,数据放在该数组中
private int top = -1; // 栈顶,初始化为-1,表示栈内无数据
public ArrayStack1(int maxsize){// 构造器
this.maxsize = maxsize;
stack = new int[maxsize];
}
public int peek(){
return stack[top];
}
public boolean isFull(){
return top == maxsize-1;
}
public boolean isEmpty(){
return top == -1;
}
public void push(int value){
if (isFull()){
System.out.println("栈满了,不能添加!~~");
return;
}
top++;
stack[top] = value;
}
public int pop(){
if (isEmpty()) {
throw new RuntimeException("栈空,没有数据!~~");
}
int value = stack[top];
top--;
return value;
}
// 遍历栈,从栈顶开始
public void list(){
if (isEmpty()){
System.out.println("栈空,无数据!~~");
return;
}
for (int i = top; i >= 0; i--){// 从上向下遍历,格式化输出
System.out.printf("stack[%d] = %d\n",i,stack[i]);
}
}
public int priority(int oper){// priority判断符号的优先级顺序,数字越大,优先级越高
if (oper == '*' || oper == '/') {
return 1;
} else if (oper == '+' || oper == '-') {
return 0;
} else {
return -1;
}
}
public boolean isOper(char val){ //判断是否为运算符。oper是运算符的意思
return val == '+' || val == '-' || val == '*' || val == '/';
}
public int cal(int a, int b, int oper){ //计算方法
int res = 0; //用于存放计算的结果
switch (oper){
case'+':
res = b + a;
break;
case'-':
res = b - a;
break;
case'*':
res = b * a;
break;
case'/':
res = b / a;
break;
}
return res;//将结果返回
}
}
2.感觉这是我目前写的最长的主函数,着实很痛苦,hiahiahia~~~
public class Calculator1 {
public static void main(String[] args) {
String e = "1+200000*3-4"; //被扫描的表达式
ArrayStack operstack = new ArrayStack(10); // 符号栈
ArrayStack numstack = new ArrayStack(10); // 数栈
int index = 0;//扫描索引
int a = 0; // 先弹出的数
int b = 0;// 后弹出的数
int res = 0; // 保存运算的结果
char ch = ' '; // 将每次扫描的字符保存在ch中
int oper = 0; // 用于接收操作符
String keepNum = ""; // 用于拼接多位数
while (true) { // 用于扫描表达式e(expression)
ch = e.substring(index,index+1).charAt(0); // 定义ch为单个字符,所以只取一个字符。
// substring(beginIndex,endIndex)。charAt(0):表示取出字符串的第一个元素(取为字符),e是字符串,要转为字符
if (operstack.isOper(ch)) { // 判断他是否为运算符,否则就转为一个数
if (!(operstack.isEmpty())) { // 判断当前符号栈是否为空
if (operstack.priority(ch) <= operstack.priority(operstack.peek())) {//符号栈中有值,就和被扫描的运算符PK,
// peek就是瞅一眼的意思,若被扫描的符号优先级小,就先不着急入栈
a = numstack.pop();
b = numstack.pop();// 然后从数栈弹出两个数
oper = operstack.pop(); //从符号栈中弹出一个字符
res = numstack.cal(a, b, oper);//将他们转入计算方法,得到结果res
numstack.push(res); //然后结果入数栈
operstack.push(ch); // 最后被扫描的运算符入符号栈
} else { //若被扫描的符号优先级大,就直接入符号栈栈
operstack.push(ch);
}
} else {//符号栈为空,直接入符号栈
operstack.push(ch);
}
}else {
keepNum += ch;
if (index == e.length()-1){
numstack.push(Integer.parseInt(keepNum));
}else if(operstack.isOper(e.substring(index+1,index+2).charAt(0))){
numstack.push(Integer.parseInt(keepNum)); // 将拼接好的数字字符转为数值再入栈
keepNum = ""; // 将keepNum清空,方便下一次使用
}
//numstack.push((ch-48)); //转为数值存入数栈中
}
index++;// 索引(指针)指向下一个字符
if (index >= e.length()){//若扫描完成,直接跳出
break;
}
}
while(true){ // 扫描完毕,就剩下同一优先级的运算符,直接从栈中依次弹出,用cal直接操作,得出结果入数栈
if (operstack.isEmpty()){
break;// 符号栈为空,结束的标志
}
a = numstack.pop();
b = numstack.pop();
oper = operstack.pop();
res = numstack.cal(a, b, oper);
numstack.push(res);
}
System.out.printf("表达式%s = %d",e,numstack.pop());//最后将数栈中的结果出栈,并输出
}
}
恩,就这样吧!