算法实例练习记录——缺少左括号的括号补全中序表达式问题(JAVA实现)

 算法练习记录——问题描述:

  •  编写一段程序,给定一个缺少左括号的表达式,并打印出,补全括号之后的中序表达式。
  •  例如,给定输入:1 + 2 ) * 3 - 4 ) * 5 - 6 ) ) )
  •  你的程序应该输出:( ( 1 + 2 ) * ( ( 3 - 4 ) * ( 5 - 6 ) ) )

自己的一些感悟: 

1、 题目本身可能没什么难度,重点在于如何思考出栈入栈的方式。一开始我考虑的是单个字符char获取--->入栈--->出栈--->组成中序表达式,但这样会出现一个问题,就是当表达式复杂之后,无法进行回溯,在表达式的开头追加左括号。

2、后来在网上看了别人的思路,才知道要将 数字符号 和 操作符符号 进行,分别存储入栈,而且最重要的是一定要用 字符串String 这样就可以避免,上面的问题了。因为可以将一个 中序表达式——字符串,当作一个Stack的对象,来进行入栈和出栈操作。

 3、在编程过程中:

  • 解决了如何去除 初始字符串 中的 空格字符 问题——直接忽略,不进行入栈操作。

  • 解决了 两位以上数字时 将它们作为一个整体进行入栈、出栈的问题——字符串的 contains(string s) 方法。


 

 具体的代码分析,都在代码中了。

import java.util.Stack;

/*
 * 编写一段程序,给定一个缺少左括号的表达式,并打印出,补全括号之后的中序表达式。
 * 例如,给定输入:1 + 2 ) * 3 - 4 ) * 5 - 6 ) ) )
 * 你的程序应该输出:( ( 1 + 2 ) * ( ( 3 - 4 ) * ( 5 - 6 ) ) )
 */

//一个Stack实现,三个String字符串辅助完成。
/*
 * 感觉好复杂,大致思路如下:
 * 1、将操作数——0,1,2,3,4,5,6,7,8,9  和  符号——+,-,*,/ ,)  分别存储在两个字符串中,方便进行入栈处理,
 * 2、String one  负责存储 操作数,String operator  负责存储 符号,分别进行入栈(stack)操作,
 * 3、 当入栈(stack)符号里出现 ) 右括号时,进行 中序表达式 的组合——出栈 4个 字符串,
 * 4、然后在最左边添加上 ( 左括号,将组合后的 中序表达式 存储进新的String endstr 中,然后重新入栈(strack)中,最为一个stack对象,
 * 5、重复以上2,3,4步骤,指导整个给定的字符串遍历结束。
 */
/*
 * 举例:给定字符串—— 4-2)/9-8)  求中序表达式结果,stack中的变化情况如下:
 * [4]
 * [4, -]
 * [4, -, 2]
 * [4, -, 2, )]
 * [(4-2)]
 * [(4-2), /]
 * [(4-2), /, 9]
 * [(4-2), /, 9, -]
 * [(4-2), /, 9, -, 8]
 * [(4-2), /, 9, -, 8, )]
 * [(4-2), /, (9-8)]
 * [(4-2)/(9-8)]
 */

public class CompleteParenthesesOne {
	
	//整个程序用到的唯一一个栈
	private Stack<String> stack;
	
	CompleteParenthesesOne(){
		stack=new Stack<String>();
	}

	public String completeParenthesesOne(String str) {
		
		//存储 数字0-9
		String one=new String();
		//存储 +-*/)这些符号
		String operator=new String();
		//存储中序表达式的结果,并进行入栈。
		String endstr=new String();
		//用来匹配 原字符串 第i个位置上,取到的字符 是不是 数字符号。 
		String nums="0123456789";

		for(int i=0; i<str.length(); i++) {
			//去除原字符串中的空格
			if(str.substring(i,i+1).equals(" ")){
				continue;
			}
			
			//判定是不是 数字 字符,是的话就继续取下一个,直到出现 符号 字符。
			//避免 两位 以上的操作数时,中序表达式,组合时出现问题。
			if(nums.contains(str.substring(i,i+1)))
			{
				one=one+str.substring(i, i+1);
				continue;
			}
			else
			{
				if(one!="") {
					stack.push(one);
					//System.out.println(stack.toString());
				}
				operator=str.substring(i,i+1);
				stack.push(operator);
			}
			//System.out.println(stack.toString());
			//开始进行 中序表达式 的组合工作,每4个stack对象为一组,进行出栈组合。
			if(operator.equals(")")) {
				for(int j=0; j<4; j++) {
					endstr=stack.pop()+endstr;
				}
				endstr="("+endstr;
				stack.push(endstr);
				endstr="";
				//System.out.println(stack.toString());
			}
			one="";
		}
		
		while(!stack.isEmpty()) {
			endstr=stack.pop()+endstr;
		}
		return endstr;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		CompleteParenthesesOne cpone=new CompleteParenthesesOne();
		
		String str="4-2)/5+2)*6-10))";
		System.out.println(cpone.completeParenthesesOne(str));
		String str1="4-2)/9-8)";
		System.out.println(cpone.completeParenthesesOne(str1));
		
		String str2=" 1 + 2 ) *   3 - 4 ) *  5 - 6 ) ) )";
		System.out.println(cpone.completeParenthesesOne(str2));
	}

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这个问题我可以帮你回答。中缀表达式转后缀表达式可以使用实现。具体的步骤如下: 1. 创建一个和一个存储后缀表达式的字符串变量。 2. 从到右遍历中缀表达式的每个字符。 3. 如果当前字符是数字或者小数点,直接将其添加到后缀表达式字符串中。 4. 如果当前字符是括号,将其压入中。 5. 如果当前字符是右括号,将中的元素依次弹出并添加到后缀表达式字符串中,直到遇到括号为止。注意:括号不需要添加到后缀表达式字符串中。 6. 如果当前字符是运算符,判断其和顶运算符的优先级,如果顶运算符优先级高于或等于当前运算符,则将顶运算符弹出并添加到后缀表达式字符串中,直到为空或者顶运算符的优先级低于当前运算符。然后将当前运算符压入中。 7. 如果当前字符是负号,需要判断其是负数还是减号。如果负号前面是括号或者是表达式的开头,说明是负数,将其视为一个整体添加到后缀表达式字符串中;否则是减号,按照运算符处理。 8. 重复步骤2-7直到遍历完中缀表达式。 9. 将中的元素依次弹出并添加到后缀表达式字符串中。 10. 返回后缀表达式字符串。 下面是一个用Java实现的示例代码,你可以参考一下: ```java public static String infixToPostfix(String infix) { Stack<Character> stack = new Stack<>(); StringBuilder postfix = new StringBuilder(); for (int i = 0; i < infix.length(); i++) { char ch = infix.charAt(i); if (Character.isDigit(ch) || ch == '.') { postfix.append(ch); } else if (ch == '(') { stack.push(ch); } else if (ch == ')') { while (!stack.isEmpty() && stack.peek() != '(') { postfix.append(stack.pop()); } stack.pop(); // 弹出括号 } else if (isOperator(ch)) { while (!stack.isEmpty() && getPriority(stack.peek()) >= getPriority(ch)) { postfix.append(stack.pop()); } stack.push(ch); } else if (ch == '-') { if (i == 0 || infix.charAt(i - 1) == '(') { // 负数的情况 postfix.append('-'); i++; while (i < infix.length() && (Character.isDigit(infix.charAt(i)) || infix.charAt(i) == '.')) { postfix.append(infix.charAt(i)); i++; } i--; } else { // 减号的情况 while (!stack.isEmpty() && getPriority(stack.peek()) >= getPriority(ch)) { postfix.append(stack.pop()); } stack.push(ch); } } } while (!stack.isEmpty()) { postfix.append(stack.pop()); } return postfix.toString(); } private static boolean isOperator(char ch) { return ch == '+' || ch == '-' || ch == '*' || ch == '/'; } private static int getPriority(char ch) { if (ch == '+' || ch == '-') { return 1; } else if (ch == '*' || ch == '/') { return 2; } else { return 0; } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值