题解 | #表达式求值#

表达式求值

http://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d

//被注释的代码是用来打印过程的
import java.util.Scanner;
import java.util.Stack;


public class Main {
	

	public static void main(String[] args) throws Exception {
		
		Scanner sc = new Scanner(System.in);
		
		if(sc.hasNext()){//每次运行只计算一个式子,假设式子格式正确
			
			calculate(convert(sc.next()));
			
		}
				
		sc.close();
	}
	
	/***
	 * 初步对式子进行处理
	 * @param s
	 * @return
	 */
	 public static String[] convert(String s){
		 
		 //============转换括号================
	        s = s.replaceAll("[\\{\\[]", "(").replaceAll("[\\}\\]]", ")");
	        //System.out.println("括号转换:" + s);
	        
	        
	     //=========分割符号与数字,目的是转字符串================
	        //System.out.println("分割:");
	        
	        StringBuffer sb = new StringBuffer(s);
	        int i = 0;//指针
	        int len = s.length();
	        char c = '0';//指针当前指向的字符,初始化为‘0’
	        char cnext = '1';//当前字符的下一个字符,初始化为‘1’
	        
	        if(sb.charAt(0) == '-'){//如果开头就是负数,那就不管,指针继续右移
	        	i++;
	        }
	        while(i < len){
	        	
	        	c = sb.charAt(i);
	        	
	        	if(!Character.isDigit(c)){//如果当前字符不是数字,则进入以下判断
	        		switch(c){
	        			case '(': {
	        				cnext = sb.charAt(i+1);
	        				if(Character.isDigit(cnext) || cnext=='-' ){
	        					sb.insert(i+1, ',');
	        					len++;
	        					i += 2;
	        				}
	        				//System.out.println(sb.toString());
	        			}break;
	        			
	        			case ')': {
	        				sb.insert(i, ',');
	        				len++;
	        				i += 2;
	        				//System.out.println(sb.toString());
	        			}break;
	        			
	        			case '+':
	        			case '*':
	        			case '/':{
	        				sb.insert(i, ',');
	        				len++;
	        				i++;
	        				sb.insert(i+1, ',');
	        				len++;
	        				i += 2;
	        				//System.out.println(sb.toString());
	        			}break;
	        			
	        			case '-': {
	        				if(Character.isDigit(sb.charAt(i-1)) || sb.charAt(i-1)==')'){
	        					sb.insert(i, ',');
		        				len++;
		        				i++;
		        				sb.insert(i+1, ',');
		        				len++;
		        				i += 2;
		        				//System.out.println(sb.toString());
	        				}else{
	        					i++;
	        				}
	        			}break;
	        			
	        			default: {
	        				i++;
	        			}break;
	        		}
	        	}
	        	else{//如果当前是数字,指针就右移
	        		i++;
	        		if(i<len-1){//指针右移后如果不是式子末尾,就接着判断
	        			while(Character.isDigit(sb.charAt(i))){//只要是数字,就一直右移下去
		        			i++;
		        			if(i>=len-1){//如果遇到末尾,则退出while!!!用break
		        				break;
		        			}
		        		}
	        		}
	        		
	        	}
	        }
	        
	        //==================生成中缀表达式数组=========================
	        int infixLen = 1;//中缀表达式长度
	        for(int k = 0; k < sb.length(); k++){//通过分隔符确认长度
	        	if(sb.charAt(k) == ','){
	        		infixLen++;
	        	}
	        }
	        
	        //System.out.println("中缀表达式长度:" + infixLen);
	        
	        String[] infix = new String[infixLen];//创建中缀表达式
	        infix = sb.toString().split(",");
	        
	        
	        //System.out.print("中缀表达式字符串转数组:");
//	        for(int k=0; k<infixLen; k++){
//	        	//System.out.print(infix[k] + " ");
//	        }
	        //System.out.println();
	        
	        //=====================转逆波兰表达式=============================
	        int blankCount = 0;//括号的数量,初始化为0
	        for(String str: infix){
	        	if(str.matches("[\\(\\)]")){//数括号
	        		blankCount++;
	        	}
	        }
	        //System.out.println("括号数:" + blankCount);
	        
	        int polandLen = infixLen-blankCount;//逆波兰式没有括号,长度要减去括号数量
	        //System.out.println("逆波兰长度:" + polandLen);
	        
	        String[] poland = new String[polandLen];//逆波兰字符串数组
	        Stack<String> opStack= new Stack<>();//符号栈
	        int j = 0;
	        
	        
	        for(String thisStr: infix){
	        	
	        	if(!thisStr.matches("^-?[0-9]+$")){//判断是否正整数或负整数
	        		switch(thisStr){
	        			case "(": {
	        				opStack.push(thisStr);
	        				
	        				//System.out.print("数字栈:");
//	        				for (int k = 0; k < j; k++){
//        			        	//System.out.print(poland[k] + " ");
//        			        }
	        				//System.out.println("\n符号栈:" + opStack + "\n");
	        			}break;
	        		
	        			case "+":
	        			case "-":{
	        				if(!opStack.isEmpty()){
	        					while(opStack.peek().matches("[+\\-*/]")){//正则表达式,匹配+-*/
	        						 
		        					poland[j] = opStack.pop(); 
		        					j++;
		        					
		        					//System.out.print("数字栈:");
//			        				for (int k = 0; k < j; k++){
//		        			        	//System.out.print(poland[k] + " ");
//		        			        }
			        				//System.out.println("\n符号栈:" + opStack + "\n");
			        				
			        				if(opStack.isEmpty()){//此处需要退出while!!!!!用break
			        					break;
			        				}
		        				}
	        					
	        					opStack.push(thisStr);
	        					
	        					
	        				}
	        				else{
	        					opStack.push(thisStr);
	        				}
	        				
	        				
	        				//System.out.print("数字栈:");
//	        				for (int k = 0; k < j; k++){
//        			        	//System.out.print(poland[k] + " ");
//        			        }
	        				//System.out.println("\n符号栈:" + opStack + "\n");
	        			}break;
	        			
	        			case "*":
	        			case "/":{
	        				if(!opStack.isEmpty()){
	        					while(opStack.peek().matches("[*/]")){//正则表达式,匹配*/
		        					poland[j] = opStack.pop(); 
		        					j++;
		        					
		        					//System.out.print("数字栈:");
//			        				for (int k = 0; k < j; k++){
//		        			        	//System.out.print(poland[k] + " ");
//		        			        }
			        				//System.out.println("\n符号栈:" + opStack + "\n");
			        				
			        				if(opStack.isEmpty()){//此处需要退出while!!!!!用break
			        					break;
			        				}
		        				}
	        					opStack.push(thisStr);
	        				}
	        				else{
	        					opStack.push(thisStr);
	        				}
	        				
	        				
	        				//System.out.print("数字栈:");
//	        				for (int k = 0; k < j; k++){
//        			        	//System.out.print(poland[k] + " ");
//        			        }
	        				//System.out.println("\n符号栈:" + opStack + "\n");
	        			}break;
	        		
	        			case ")":{
	        				while(!opStack.peek().equals("(")){
	        					poland[j] = opStack.pop(); 
	        					j++;
	        					
	        					//System.out.print("数字栈:");
//		        				for (int k = 0; k < j; k++){
//	        			        	//System.out.print(poland[k] + " ");
//	        			        }
		        				//System.out.println("\n符号栈:" + opStack + "\n");
	        				}
	        				opStack.pop();
	        				
	        				//System.out.print("数字栈:");
//	        				for (int k = 0; k < j; k++){
//        			        	//System.out.print(poland[k] + " ");
//        			        }
	        				//System.out.println("\n符号栈:" + opStack + "\n");
	        			}break;
	        			
	        			default: {
	        				System.out.println("error");
	        				
	        				//System.out.print("数字栈:");
//	        				for (int k = 0; k < j; k++){
//        			        	//System.out.print(poland[k] + " ");
//        			        }
	        				//System.out.println("\n符号栈:" + opStack + "\n");
	        			}break;
	        		}
	        	}else{
        			poland[j] = thisStr; 
					j++;
					
					//System.out.print("数字栈:");
//    				for (int k = 0; k < j; k++){
//			        	//System.out.print(poland[k] + " ");
//			        }
    				//System.out.println("\n符号栈:" + opStack + "\n");
        		}
	        }
	        
	        while(!opStack.isEmpty()){
	        	poland[j] = opStack.pop(); 
				j++;
				
				//System.out.print("数字栈:");
//				for (int k = 0; k < j; k++){
//		        	//System.out.print(poland[k] + " ");
//		        }
				//System.out.println("\n符号栈:" + opStack + "\n");
	        }
	        	
	        //System.out.print("逆波兰表达式:");
//	        for (int k = 0; k < polandLen; k++){
//	        	//System.out.print(poland[k] + " ");
//	        }
	        //System.out.println("\n操作符栈清空:" + opStack.toString());
	        
	        return poland;
	    }
	
	 /***
	  * 对逆波兰表达式计算结果
	  * @param poland
	  */
	 public static void calculate(String[] poland) {
	        Stack<Long> numStack = new Stack<>();
	        
	        for(String s: poland){
	        	if(!s.matches("^-?[0-9]+$")){//判断是否正整数或负整数
	        		switch(s){
	        		
	        			case "+":{
	        				long num = numStack.pop();
	        				numStack.push(num+numStack.pop());
	        			}break;
	        			case "-":{
	        				long num = numStack.pop();
	        				numStack.push(numStack.pop()-num);
	        			}break;
	        			
	        			case "*":{
	        				long num = numStack.pop();
	        				numStack.push(num*numStack.pop());
	        			}break;
	        			
	        			case "/":{
	        				long num = numStack.pop();
	        				numStack.push(numStack.pop()/num);
	        			}break;
	        		
	        			default: {
	        				System.out.println("error");
	        			}break;
	        		}
	        	}else{
        			numStack.push(Long.parseLong(s));
        		}
	        }
	        System.out.println(numStack.pop());
	 }
	
}
全部评论

相关推荐

牛客717484937号:双飞硕没实习挺要命的
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务