中缀表达式(含括号计算) 韩顺平老师基础上加的

package exercise.stack;

/**

  • 中缀表达式

  • 遇左括号直接放进运算符栈,…遇见右括号,若当前运算符栈顶不是左括号,则退出一个运算符,两个操作数,直到运算符栈顶是和右括号配对的左括号,这时左括号就可以出栈了

  • @ClassName: NifixExpression

  • @author: fan

  • @date: 2020年6月12日 上午11:18:53

  • @version 1.0v
    /
    public class NifixExpression {
    public static void main(String[] args) {
    String expression = “13+256-2”;//130
    //String expression = "(20+(3
    (3+1*4+5)-8))*2";// 96
    ArrayStack numStack = new ArrayStack(10);
    ArrayStack operStack = new ArrayStack(10);

     // 需要定义的相关变量
     int index = 0;// 指针,用来指定当前扫描到第几个数
     int num1 = 0;
     int num2 = 0;
     int oper = 0;
     int res = 0;
     char ch = ' ';// 把每次扫描到的结果保存到ch中
     String keepNum = "";// 用于拼接多位数
     while (true) {
     	// 2+(3*(1+4*5)-2)
     	// 依次得到每一个数
     	ch = expressin.substring(index, index + 1).charAt(0);
     	// 判断ch是什么
     	if (operStack.isOper(ch)) {
     		if (operStack.isLeftBracket(ch) == 0) {
     			operStack.push(ch);
     		} else if (operStack.isLeftBracket(ch) == 1) {
     			while (true) {
     				num1 = numStack.pop();
     				num2 = numStack.pop();
     				oper = operStack.pop();
     				res = operStack.cal(num1, num2, oper);
     				numStack.push(res);
     				if (operStack.peek() == '(') {
     					break;
     				}
     			}
     			// 弹出左括号
     			operStack.pop();
     		} else {
     			// 判断是不是空的
     			if (!operStack.isEmpty()) {
     				if (operStack.peek() == '(') {
     					operStack.push(ch);
     				} else {
     					// 当前这个小于或等于
     					if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
     						num1 = numStack.pop();
     						num2 = numStack.pop();
     						oper = operStack.pop();
     						res = operStack.cal(num1, num2, oper);
     						numStack.push(res);
     						// 还要把当前扫描到的符号入栈
     						operStack.push(ch);
     					} else {
     						operStack.push(ch);
     					}
     				}
     			} else {
     				operStack.push(ch);
     			}
     		}
    
     	} else {
     		// numStack.push(ch - 48);//ASCII 表中对比,char和int 相差48 数值1 对应的ASCII 为1, 字符'1'
     		// 对应的ASCII 为49
     		// 当是连续多位数时 当发现是数时,要向后面多看一位,后面一位是符号是才入栈,否则继续扫描
     		keepNum += ch;
     		if (index == expressin.length() - 1) {
     			numStack.push(Integer.parseInt(keepNum));
     		} else {
     			// 这里只是看一下,!!!! 不是index++
     			if (operStack.isOper(expressin.substring(index + 1, index + 2).charAt(0))) {
     				// 如果最后一位是运算符则入栈
     				numStack.push(Integer.parseInt(keepNum));
     				// 很重要很重要!!!!!
     				keepNum = "";
     			}
     		}
    
     	}
    
     	index++;
     	if (index >= expressin.length()) {
     		break;
     	}
     }
    
     while (true) {
     	if (operStack.isEmpty()) {
     		break;
     	}
     	num1 = numStack.pop();
     	num2 = numStack.pop();
     	oper = operStack.pop();
     	res = operStack.cal(num1, num2, oper);
     	numStack.push(res);
     }
    
     System.out.println("最后的结果是:" + numStack.pop());
    

    }
    }

class ArrayStack {
private int maxSize;// 栈的大小
private int[] arr;// 用数组来模拟栈
private int top = -1;// 表是栈顶

public ArrayStack(int maxSize) {
	super();
	this.maxSize = maxSize;
	arr = new int[maxSize];
}

// 栈满
public boolean isFull() {
	return top == maxSize - 1;
}

// 栈空
public boolean isEmpty() {
	return top == -1;
}

// 入栈
public void push(int value) {
	// 先判断栈满了没有
	if (isFull()) {
		System.out.println("栈满了");
		return;
	}

	arr[++top] = value;
}

// 出栈
public int pop() {
	if (isEmpty()) {
		System.out.println("栈空了");
		throw new RuntimeException("栈空了");
	}

	return arr[top--];
}

// 查看栈顶
public int peek() {
	if (isEmpty()) {
		System.out.println("栈空了");
		throw new RuntimeException("栈空了");
	}
	return arr[top];
}

public void list() {
	if (isEmpty()) {
		System.out.println("栈空了");
		throw new RuntimeException("栈空了");
	}

	for (int i = top; i >= 0; i--) {
		System.out.printf("栈中的元素%d\n", arr[i]);
	}
}

/**
 * 判断是不是一个运算符
 * 
 * @param val
 * @return
 */
public boolean isOper(char val) {
	return val == '+' || val == '-' || val == '*' || val == '/' || val == '(' || val == ')';
}

public int isLeftBracket(char val) {
	if (val == '(') {
		return 0;
	} else if (val == ')') {
		return 1;
	} else {
		return -1;
	}
}

/**
 * 判断优先级 自己控制
 * 
 * @param oper
 * @return
 */
public int priority(int oper) {
	if (oper == '(' || oper == ')') {
		return 2;
	} else if (oper == '*' || oper == '/') {
		return 1;
	} else if (oper == '+' || oper == '-') {
		return 0;
	} else {
		return -1;// 表示当前只支持+ — * / 这是四种
	}
}

/**
 * 计算
 * 
 * @param nmu1
 * @param num2
 * @param oper
 * @return
 */
public int cal(int num1, int num2, int oper) {
	int res = 0;
	switch (oper) {
	case '+':
		res = num1 + num2;
		break;
	case '-':
		res = num2 - num1;
		break;
	case '*':
		res = num1 * num2;
		break;
	case '/':
		res = num2 / num1;
		break;

	default:
		break;
	}

	return res;

}

}

上面所有的都是代码,我放的是一个java文件,变量expression 显示的点问题,

注意黑色边框外的大括号也是代码里面的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值