简单,java解析算数表达式

本文介绍了一种将中缀表达式转换为后缀表达式的方法,并通过具体示例详细展示了转换过程及核心算法。该算法适用于计算器程序等需要进行表达式求值的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此示例值只使用了+ - * / 和小括号,但基本思路已经很清晰了!!!

解析成后缀表达式,用之前的逆波兰java的博客里面的java代码算出结果!


/*
	 * 例如:1*(2+3+(5-4))+6
	 * 
	 * 开始括号:(  [  {
	 * 结束括号:}  ]  )
	 * 
	 * 基本思路:
	 * 1.  在解析的时候,因为如果解析到6的话,已经到结尾了,但程序不知道是否,应该取出栈中存放的运算符号。
	 *     也可以在遍历结束之后,在取出栈中的运算符,但我选择的是在原字符串基础上加一个结束标志,我使用的是!(叹号)
	 * 2.  如果是数字就加入到代表后缀表达式代表的字符串中
	 * 3.  如果是运算符(+ - * /)就都压入栈中
	 * 4.  如果是大中小开始括号,也同样压入栈中
	 * 5.  在栈中没有括号的情况下:
	 *                碰到 加号(+)或者减号( -),就取出栈中所有的运算符,在将+或—压入栈中
	 * 6.  在栈中有括号的情况下:
	 *                碰到 加号(+)或者减号( -),取出栈中的运算符,直到碰到开始括号为止(开始括号不取出来!!!),
	 *                在将当前+或者-压入栈中。
	 * 7.  在栈中有括号的情况下:
	 *                碰到结束括号,取出栈中的运算符,直到取出与之配置开始括号为止(开始括号也取出来!!!)。
	 * 8.  碰到结束标志(!)如果栈中不为空全部取出,结束遍历算数表达式。
	 * 
	 * 
	 * 示例解析:1*(2+3+(5-4))+6!
	 *  算数表达式               栈(解析完算数表达式后)     后缀表达式
	 *  1                                                    1
	 *  1*                           *                       1
	 *  1*(                          *(                     1
	 *  1*(2                         *(                     12
	 *  1*(2+(应该执行第5步)       *(+                    12
	 *  1*(2+3                       *(+                    123
	 *  1*(2+3+                      *(+                    123+
	 *  1*(2+3+(                     *(+(                  123+
	 *  1*(2+3+(5                    *(+(                  123+5
	 *  1*(2+3+(5-                   *(+(-                 123+5
	 *  1*(2+3+(5-4                  *(+(-                 123+54
	 *  1*(2+3+(5-4)(应该执行第6步)*(+                    123+54-
	 *  1*(2+3+(5-4))                *                       123+54-+
	 *  1*(2+3+(5-4))+               +                       123+54-+*
	 *  1*(2+3+(5-4))+6              +                       123+54-+*6
	 *  1*(2+3+(5-4))+6!                                     123+54-+*6+
	 *  
	 */
	@Test
	public void test() {
		String str = "2+(1+(2*4/(2/1))*6+(1-2))*4+5";
		//应先判断算数表达式中的括号是否匹配
		String expression = this.createSuffixExp(str);
		System.out.println(expression); // 212421//*6*+12-+4*+5+
	}
	
	public String createSuffixExp(String str) {
		int num = 0;      //记录栈中的开始括号个数
		int stackLen = 0;
		String template = "";
		Stack<Character> stack = new Stack<Character>(30);
		
		str = str + "!";     //第1步,要在这里加,不要在for循环的执行条件里面加!会有字符串的相关问题!
		
		for(int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			
			if(c == '(') {
				++num;
				stack.push(c);      //第4步
			} else if (c == '-' || c == '+' || c == '!') {  //判断是否是 + - !
				if(num > 0) { //判断是否有开始括号
					stackLen = stack.getLen();
					for(int j = 0; j < stackLen; j++ ) {     //第6步
						char element = stack.peak();
						if(element == '(') {
							break;
						}
						template += stack.pop();
					}
				} else {     //第5步,栈中没有括号
					if(stack.getLen() != 0) {
						/*
						 * int stackLen = stack.getLen();应当先获得stack的大小
						 * 因为每当stack移除一项之后,for循环判断stack.getLen都会减1
						 * 也就是j在不断增减,这样就会出现问题!!!
						 */
						stackLen = stack.getLen();
						for(int j = 0; j < stackLen; j++ ) {
							template += stack.pop();
						}
					}
				}
				
				if(c == '!') {     //第8步
					break ;
				}
				stack.push(c);     //第3步
			} else if (c == '*' || c == '/') {     //判断是否是 *  /
				stack.push(c);     //第3步
			} else if (c == ')') {
				stackLen = stack.getLen();
				for(int k = 0; k < stackLen; k++) {     //第7步
					char element = stack.pop();
					if(element == '(') {
						break;
					}
					template += element;
				}
				--num;
			} else {     //第2步
				template += c;
			}
		}
		return template;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值