java 实现 中序表达式转后序表达式(逆波兰式) 以及 后序表达式求值

第一次写博客,还是个学生,没有什么经验,只是单纯的记录下自己实现一个问题的方法与思想,如有错误以及不完善之处,请各路大神批评指出。

java实现逆波兰式,如何转换参考博客  https://blog.csdn.net/sgbfblog/article/details/8001651

大概思想:跟参考博客的思想差不多,单代码完全自己思考,实现过程有较多的if..else语句 看起来可能会有点晕。各处都有注释有不懂的可以私信我。

这个程序还有一个好处是在于求后续表达式的时候,如果指定序列有其他字符(可能误输入)也可以生成对应的后续表达式,还会提醒哪个位置是哪个字符有误。比如指定序列为 String str = "3¥+9*7+(2*1】+7)*2^"; 程序运行结果如下:

运行截图

不足之处在于求和的时候,指定序列的数字的值只能是0到9之间,不能大于9.

完整代码如下:

package reversePolish;

import java.util.*;


public class ReversePolish{
	
	public static void main(String args[]){
		String str = "3+9*7+(2*1+7)*2";
		System.out.println(reversePolish(str));
		System.out.println(sumReversePolish(reversePolish(str)));
	}
	
	public static String reversePolish(String str){
		//String[] strArray = str.split("");
		String str1;
		char[] strArray = str.toCharArray();
		String[] operator = {"+","-","/","*","(",")"};
		List<String> list = Arrays.asList(operator);
		LinkedList<String> list1 = new LinkedList<String>();  //输出栈
		LinkedList<String> list2 = new LinkedList<String>();   //操作符栈
		for(int i = 0;i < strArray.length; i++){
			/*该部分为查bug过程 ,一步一步看输出是否一致
			 if(i == 14) {
				Iterator<String> it1 = list1.iterator();
				Iterator<String> it2 = list2.iterator();
				while(it1.hasNext()) {
					System.out.print(it1.next() + " ,");
				}
				System.out.println();
				while(it2.hasNext()) {
					System.out.print(it2.next() + " ,");
				}
				System.out.println();
				//System.exit(-1);
			}*/
			if(Character.isDigit(strArray[i]) || Character.isLetter(strArray[i])){     //如果是操作数或者字母直接输出
				list1.add(Character.toString(strArray[i]));
			}else if(list.contains(Character.toString(strArray[i]))){
				if(list2.size() == 0){
					list2.addFirst(Character.toString(strArray[i]));                 //操作符入栈
				}else {
					if(Character.toString(strArray[i]).equals("(")){
						list2.addFirst(Character.toString(strArray[i]));                 //操作符入栈
					}
					else if(Character.toString(strArray[i]).equals(")")){
						String[] strA = list2.toArray(new String[0]);
						for(int j = 0;j < strA.length;j++) {
							do{
								if(list2.size() == 0) {
									//这里写不写都行,因为有括号不可能在第一个位置
								}else {
									if(strA[j].equals("(")){
										list2.pollFirst();
										j = strA.length - 1;
									}else{
										list1.add(list2.pollFirst());
									}
								}
							}while(strA[j].equals("quit"));
						}
					}
					//如果是加号或者减号,则除了遇到左括号,全部要出栈
					else if(Character.toString(strArray[i]).equals("+") || Character.toString(strArray[i]).equals("-")){
						String[] strB = list2.toArray(new String[0]); //要对操作符栈进行操作,所以不能使用Iterator进行操作(iterator操作的时候不能进行list的改动)
						if(strB[0].equals("(")){
							list2.addFirst(Character.toString(strArray[i]));
						}else {
							for(int k = 0;k < strB.length;k++) {
								if(strB[k].equals("(")) {
									list2.addFirst(Character.toString(strArray[i]));
									k = strB.length - 1;  //遇到左括号直接入栈,跳出循环,下面类似
								}else {
									do{
										if(list2.size() == 0) {
											list2.addFirst(Character.toString(strArray[i]));
										}else {		
											list1.add(list2.pollFirst());
										}
									}while(strB[k].equals("quit"));
								}
							}
						}
						if(list2.size() == 0){  //因为栈里面的数据都出栈了,所以刚扫描的符号要进栈,前提是没有左括号
							list2.addFirst(Character.toString(strArray[i]));
						}
					}
					//如果是乘号或者除号,栈顶元素为+或者-或者(进栈,*或者、出栈
					else if(Character.toString(strArray[i]).equals("*") || Character.toString(strArray[i]).equals("/")){	
						String[] strC = list2.toArray(new String[0]);	
						if(strC[0].equals("(")) {
							list2.addFirst(Character.toString(strArray[i]));
						}else {
							for(int l = 0;l < strC.length;l++) {
								if(strC[l].equals("(")) {
									list2.addFirst(Character.toString(strArray[i]));
									l = strC.length - 1;
								}else {
									do{
										if(list2.size() == 0){
											list2.addFirst(Character.toString(strArray[i]));
										}else {
											if(strC[l].equals("*") || strC[l].equals("/")){
												list1.add(list2.pollFirst());
											}else if(strC[l].equals("+") || strC[l].equals("-")){
												list2.addFirst(Character.toString(strArray[i]));
											}else {}
										}
									}while(strC[l].equals("quit"));
								}
							}
						}
						if(list2.size() == 0){
							list2.addFirst(Character.toString(strArray[i]));
						}
					}
				}
			}
			else {
				System.out.println("输入字符串中的第个" + i + "符号 " + strArray[i] + "无法识别,请核对!");
			}
		}
		//字符串扫描完毕,把操作符栈剩下的操作符依次取出到输出栈
		int len = list2.size();
		for(int p = 0;p < len;p++){
			list1.add(list2.pollFirst());
		}
		String[] strOutput = list1.toArray(new String[0]);  
		StringBuffer sb = new StringBuffer();
		for(int i = 0; i < strOutput.length; i++){
		 sb. append(strOutput[i]);
		}
		str1 = sb.toString();
		
		return str1;
	}
	
	
	//后序表达式求值,要求中序序列只能有数字不能有字母
	public static int sumReversePolish(String str){          
		//char[] strArray = str.toCharArray();
		String[] strArray = str.split("");
		LinkedList<Integer> list1 = new LinkedList<Integer>(); //存操作数
		int a = 0,b = 0,sum = 0;
		for (int i = 0; i < strArray.length; i++) {
			 if(strArray[i].equals("+") || strArray[i].equals("-") || strArray[i].equals("*") || strArray[i].equals("/")){
				sum = 0;
				a = list1.pollFirst();  //获取第一个数
				b = list1.pollFirst();  //获取第二个数
				switch(strArray[i]) {
					case "+": sum = b + a; list1.addFirst(sum); break;
					case "-": sum = b - a; list1.addFirst(sum); break;
					case "*": sum = b * a; list1.addFirst(sum); break;
					case "/": sum = b / a; list1.addFirst(sum); break;
				}
			}else {				
					list1.addFirst(Integer.valueOf(strArray[i]).intValue()); //数字的话直接加入列表
			}
		}
		return sum;
	}
}

如若转载请注明出处,谢谢。

猜你喜欢

转载自blog.csdn.net/Lcaicp/article/details/82951442