• 逆波兰表达式


    正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便。
    
    例如:3 + 5 * (2 + 6) - 1
    
    而且,常常需要用括号来改变运算次序。
    
    相反,如果使用逆波兰表达式(前缀表达式)表示,上面的算式则表示为:
    
    - + 3 * 5 + 2 6 1
    
    不再需要括号,机器可以用递归的方法很方便地求解。
    
    为了简便,我们假设:
    
    1. 只有 + - * 三种运算符
    2. 每个运算数都是一个小于10的非负整数
    
    下面的程序对一个逆波兰表示串进行求值。
    其返回值为一个结构:其中第一元素表示求值结果,第二个元素表示它已解析的字符数。
    struct EV
    {
    	int result;  //计算结果 
    	int n;       //消耗掉的字符数 
    };
    
    struct EV evaluate(char* x)
    {
    	struct EV ev = {0,0};
    	struct EV v1;
    	struct EV v2;
    
    	if(*x==0) return ev;
    	
    	if(x[0]>='0' && x[0]<='9'){
    		ev.result = x[0]-'0';
    		ev.n = 1;
    		return ev;
    	}
    	
    	v1 = evaluate(x+1);
    	v2 = _____________________________;  //填空位置
    	
    	if(x[0]=='+') ev.result = v1.result + v2.result;
    	if(x[0]=='*') ev.result = v1.result * v2.result;
    	if(x[0]=='-') ev.result = v1.result - v2.result;
    	ev.n = 1+v1.n+v2.n;
    
    	return ev;
    }
    
    

    请分析代码逻辑,并推测划线处的代码,通过网页提交。

    注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

    答案 evaluate(x+v1.n+1)(10分)

    正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便。
    
    例如:3 + 5 * (2 + 6) - 1
    
    而且,常常需要用括号来改变运算次序。
    
    相反,如果使用逆波兰表达式(前缀表达式)表示,上面的算式则表示为:
    
    - + 3 * 5 + 2 6 1
    
    不再需要括号,机器可以用递归的方法很方便地求解。
    
    为了简便,我们假设:
    
    1. 只有 + - * 三种运算符
    2. 每个运算数都是一个小于10的非负整数
    
    下面的程序对一个逆波兰表示串进行求值。
    其返回值为一个结构:其中第一元素表示求值结果,第二个元素表示它已解析的字符数。
    	static int[] evaluate(String x)
    	{
    		if(x.length()==0) return new int[] {0,0};
    		
    		char c = x.charAt(0);
    		if(c>='0' && c<='9') return new int[] {c-'0',1};
    		
    		int[] v1 = evaluate(x.substring(1));
    		int[] v2 = __________________________________________;  //填空位置
    		
    		int v = Integer.MAX_VALUE;
    		if(c=='+') v = v1[0] + v2[0];
    		if(c=='*') v = v1[0] * v2[0];
    		if(c=='-') v = v1[0] - v2[0];
    		
    		return new int[] {v,1+v1[1]+v2[1]};
    	}
    

    请分析代码逻辑,并推测划线处的代码,通过网页提交。

    注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

    答案 (10分)

    代码是以递归方式求前缀表达式,当第一个字符是运算符时,把后面的字符串分为两部分各自求出结果,然后用这个运算符计算,显然先知道了v1,那么v1的结果和所用的字符数都知道了,v2就应该时剩下的部分了。

    代码:

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    
    using namespace std;
    struct EV
    {
        int result;  //计算结果
        int n;       //消耗掉的字符数
    };
    
    struct EV evaluate(char* x)
    {
        struct EV ev = {0,0};
        struct EV v1;
        struct EV v2;
    
        if(*x==0) return ev;
    
        if(x[0]>='0' && x[0]<='9'){
            ev.result = x[0]-'0';
            ev.n = 1;
            return ev;
        }
    
        v1 = evaluate(x+1);
        v2 = evaluate(x+v1.n+1);  //填空位置
    
        if(x[0]=='+') ev.result = v1.result + v2.result;
        if(x[0]=='*') ev.result = v1.result * v2.result;
        if(x[0]=='-') ev.result = v1.result - v2.result;
        ev.n = 1+v1.n+v2.n;
    
        return ev;
    }
    int main() {
        char *t = "-+3*5+261";
        printf("%d",evaluate(t).result);
    }
    public class Main {
        static int[] evaluate(String x)
        {
            if(x.length()==0) return new int[] {0,0};
            
            char c = x.charAt(0);
            if(c>='0' && c<='9') return new int[] {c-'0',1};
            
            int[] v1 = evaluate(x.substring(1));
            int[] v2 = evaluate(x.substring(v1[1] + 1));  //填空位置
            
            int v = Integer.MAX_VALUE;
            if(c=='+') v = v1[0] + v2[0];
            if(c=='*') v = v1[0] * v2[0];
            if(c=='-') v = v1[0] - v2[0];
            
            return new int[] {v,1+v1[1]+v2[1]};
        }
        public static void main(String[] args) {
            System.out.println(evaluate("-+3*5+261")[0]);
        }
    }
  • 相关阅读:
    Fedora 19 配置参考
    Lua 函数、闭包、尾调用总结
    基于MFC简单图片裁剪工具
    【OpenGL 学习笔记04】顶点数组
    【OpenGL 学习笔记03】点画多边形
    【OpenGL 学习笔记02】宽点画线
    【OpenGL 学习笔记01】HelloWorld示例
    【SSH + BootStrap】实现的无线点餐系统
    【C++ 基础 11】 函数指针总结
    【C++基础 10】四种cast转换的区别
  • 原文地址:https://www.cnblogs.com/8023spz/p/10369179.html
Copyright © 2020-2023  润新知