精华内容
下载资源
问答
  • 算符优先法】——表达式求值

    千次阅读 2019-05-07 14:01:04
    算符优先法需要设立两个栈。(本来不应该是这两个单词,但是本教主觉得更加重要的是命名的易区分性) 1. 寄存操作数的栈`nums` 2. 寄存操作符的栈`opters` ### 基本思想 1. 首先置`nums`栈为空,表达式起始符`#`...

    一、算符优先法


    前提

    算符优先法需要设立两个栈。(本来不应该是这两个单词,但是本教主觉得更加重要的是命名的易区分性)

    1. 寄存操作数的栈nums
    2. 寄存操作符的栈opters

    基本思想

    1. 首先置nums栈为空,表达式起始符#opters栈的栈底元素

    2. 依次读入表达式中的每个字符,用isOpters()判断是否是操作数

      1. 如果是操作数则进nums

      2. 如果是操作符,则将栈顶元素和该操作符比较优先级(栈顶操作符和该操作符比较优先级)循环进行直到读取到截断符号#

        1. 若栈顶操作符优先级低,则将该操作符入栈
        2. 如果相等,那么就说明是括号,成对消去(弹出栈中的左括号即可)
        3. 如果栈顶操作符优先级高,则说明栈顶的操作符就是目前需要参与运算的运算符。

    更简单的后缀表示法

    1. 只需一个操作数栈
    2. 将中缀表达式转换为后缀表达式,因为计算机更擅长于处理后缀表达式。(参考博客中缀表达式转后缀表达式(c++)
    3. 操作数栈弹出两个操作数,和剩下的操作符参与运算



    二、源码


    caculate.h文件

    1. 相比较从黑窗口读取缓存区的字符,直接处理字符串的情况显得更加大众一点儿,所以选择了将中缀表达式存放在字符串中。

    2. string类重载了[]符号,因而可以像字符数组一样直接使用str[i]来获取string对象的第i个位置的字符。

    3. 将表示intchar型转换为int型,最常用的办法是利用ASCII表,直接减去'\0'的ASCII值48就可以获取对应的int值。

    #pragma once
    #ifndef caculate_H
    #include<iostream>
    #include<stdlib.h>
    #include<stack>
    using namespace std;
    
    //算符优先法
    class Caculate {
    public:
    	static const char ERROR = 'E';
    	stack<int> nums;														//操作数栈
    	stack<char> opters;														//操作符栈
    	string expression;														//中缀表达式
    
    public:
    	Caculate(string expression) {
    		this->expression = expression;
    	}
    
    	//计算结果
    public:
    	int caculate() {
    		int i = 0;															//用来读取下一位的位置指针
    		//1.将 # 入栈
    		opters.push('#');
    		while (expression[i] != '#' || opters.top() != '#') {
    			//2.如果是操作数,则入栈
    			if (!this->isOpters(expression[i])) {
    				nums.push(expression[i] - 48);
    				i++;
    			}
    			//3.如果是操作符,则与栈顶符号比较优先级,来决定是否计算
    			else if (this->isOpters(expression[i])) {
    				switch (this->compare(opters.top(), expression[i])) {
    				case '<':													//栈顶元素优先级低:符号入栈
    					opters.push(expression[i]);
    					i++;
    					break;
    				case '=':													//优先级相等:说明是栈顶的 ( 和 expression的 ),则消去一对括号
    					opters.pop();
    					i++;
    					break;
    				case '>':													//栈顶元素优先级高:计算并将计算结果入栈
    					int opval2 = nums.top();
    					nums.pop();
    					int opval1 = nums.top();
    					nums.pop();
    					//将计算结果入栈
    					int result = this->caculate(opval1, opters.top(), opval2);
    					nums.push(result);
    					//弹出运算符
    					opters.pop();
    					break;
    				}
    			}
    		}
    		//4.计算完后返回栈顶元素
    		return nums.top();
    	}
    
    
    	//计算两个数的结果
    public:
    	int caculate(int a, char opters, int b) {
    		if (opters == '+') {
    			return a + b;
    		} else if (opters == '-') {
    			return a - b;
    		} else if (opters == '*') {
    			return a * b;
    		} else if (opters == '/') {
    			return a / b;
    		} else {
    			cout << "操作符有误!";
    			return 0;
    		}
    	}
    
    
    	//判断是否是操作符
    public:
    	bool isOpters(char opters) {
    		return (opters == '+' ||
    			opters == '-' ||
    			opters == '*' ||
    			opters == '/' ||
    			opters == '(' ||
    			opters == ')' ||
    			opters == '#') ? true : false;
    	}
    
    
    	//比较操作符的优先级
    public:
    	char compare(char op1, char op2) {
    		if (op1 == '+' || op1 == '-') {
    			if (op2 == '+' || op2 == '-' || op2 == ')' || op2 == '#') {
    				return '>';
    			} else {
    				return '<';
    			}
    		} else if (op1 == '*' || op1 == '/') {
    			if (op2 == '(') {
    				return '<';
    			} else {
    				return '>';
    			}
    		} else if (op1 == '(') {
    			if (op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/' || op2 == '(') {
    				return '<';
    			} else if (op2 == ')') {
    				return '=';
    			} else {
    				cout << "输入有误";
    				return ERROR;
    			}
    		} else if (op1 == ')') {
    			if (op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/' || op2 == ')' || op2 == '#') {
    				return 1;
    			} else if (op2 == '(') {
    				cout << "输入有误";
    				return ERROR;
    			}
    		} else if (op1 == '#') {
    			if (op2 == ')') {
    				cout << "输入有误";
    				return ERROR;
    			} else if (op2 == '#') {
    				return 0;
    			} else {
    				return '<';
    			}
    		}
    	}
    };
    #endif // !caculate_H
    

    算符间的优先关系

    在这里插入图片描述

    	//比较操作符的优先级
    public:
    	char compare(char op1, char op2) {
    		if (op1 == '+' || op1 == '-') {
    			if (op2 == '+' || op2 == '-' || op2 == ')' || op2 == '#') {
    				return '>';
    			} else {
    				return '<';
    			}
    		} else if (op1 == '*' || op1 == '/') {
    			if (op2 == '(') {
    				return '<';
    			} else {
    				return '>';
    			}
    		} else if (op1 == '(') {
    			if (op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/' || op2 == '(') {
    				return '<';
    			} else if (op2 == ')') {
    				return '=';
    			} else {
    				cout << "输入有误";
    				return ERROR;
    			}
    		} else if (op1 == ')') {
    			if (op2 == '+' || op2 == '-' || op2 == '*' || op2 == '/' || op2 == ')' || op2 == '#') {
    				return 1;
    			} else if (op2 == '(') {
    				cout << "输入有误";
    				return ERROR;
    			}
    		} else if (op1 == '#') {
    			if (op2 == ')') {
    				cout << "输入有误";
    				return ERROR;
    			} else if (op2 == '#') {
    				return 0;
    			} else {
    				return '<';
    			}
    		}
    	}
    

    main.cpp文件

    #include<iostream>
    #include"caculate.h"
    using namespace std;
    
    int main() {
    	Caculate c("3*(7-2)#");
    	int m = c.caculate();
    	cout << m << endl;
    }
    

    在这里插入图片描述

    展开全文
  • 算符优先法对算术表达式求值(六)

    万次阅读 多人点赞 2018-11-23 00:19:22
    掌握栈在解决实际问题中的应用,设计一个程序,演算用算符优先法对算术表达式求值的过程,利用算符优先关系,实现对算术四则混合运算表达式的求值 。。挺难的。。 思路在这! 思路 这个程序是这样,当你点击运行它的...

    18.11.23
    这是一道最近刚上的实验课的题目。。。。

    基于C语言,欢迎指正

    实验要求

    掌握栈在解决实际问题中的应用,设计一个程序,演算用算符优先法对算术表达式求值的过程,利用算符优先关系,实现对算术四则混合运算表达式的求值

    。。挺难的。。

    思路在这!

    思路

    这个程序是这样,当你点击运行它的时候,你需要输一个表达式,然后按个回车,答案就出来了,跟个计算器一样

    那么,在一开始,我们需要一个数组,来存入你所输入的表达式,这样就得到了一个字符数组,然后呢,我们需要创建两个栈,一个用来存运算符,我们叫他运算符栈opter,一个用来存操作数,我们叫它操作数栈opnd,然后我们开始读入我们输入的表达式,读到一个操作符就加到一个新的字符数组,比如说,23+1这个式子,先读入一个’2’存入字符数组,在读入一个’3’存入字符数组,当读到’+’ ,这个时候字符数组有两个元素,给字符数组的第三号位加上一个’\0’,就变成了一个字符串,这样用atof函数就是可以把这个字符串变成浮点型从而可以参与运算(不然如果还是字符状态是不能参与运算的),然后把得到的这个23压入操作数栈中进行相应操作,相应操作如下:

    这是来自学校发的实验报告册上的:(认真看还是看的懂的)
    (1)首先将操作数栈opnd设为空栈,而将’#'作为运算符栈opter的栈底元素,这样的目的是判断表达式是否求值完毕。
    (2)依次读入表达式的每个字符,表达式须以’#‘结尾,若是操作数则入栈opnd,若是运算符,则将此运算符c与opter的栈顶元素top比较优先级后执行相应的操作,具体操作如下:
    (i)若top的优先级小于c,即top<c,则将c直接入栈opter,并读入下一字符赋值给c;
    (ii)若top的优先级等于c,即top=c,则弹出opter的才顶元素,并读入下一字符赋值给c,这一步目的是进行括号操作;
    (iii)若top优先级高于c,即top>c,则表明可以计算,此时弹出opnd的栈顶两个元素,并且弹出opter栈顶的的运算符,计算后将结果放入栈opnd中。直至opter的栈顶元素和当前读入的字符均为’#’,此时求值结束。

    在这里插入图片描述
    表中需要注意的是θ1为opter的栈顶元素,θ2为从表达式中读取的操作符,此优先级表可以用二维数组实现。

    有.思路了,咱们把整个程序拆开来看看

    我们需要的东西

    1. 一堆头文件
    2. 一个用于优先级比较的数组,
    3. 两个栈
    (我们这里用的是顺序栈)

    其中,这个用于运算符比较的数组是这个
    “>><<<>>”,
    “>><<<>>”,
    “>>>><>>”,
    “>>>><>>”,
    “<<<<<=?”,
    “>>>>?>>”,
    “<<<<<?=”
    即这个
    在这里插入图片描述

    代码如下

    #include<stdio.h>
    #include<stdlib.h>//包含exit()函数
    #include<string.h>//跟字符处理有关的头文件
    #include<math.h>
    
    #define Stack_Size 1000    //认为Stack_Size为1000
    
    char cmp[7][8]= {">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=?",">>>>?>>","<<<<<?="};
    
    typedef struct{//定义一个运算符栈
        char Elem[Stack_Size];
        int top;//标记变量,记录表尾的变化
    }Opter;
    
    typedef struct{//定义一个操作数栈
        double Elem[Stack_Size];
        int top;
    }Opnd;
    
    

    准备活动完成了,接下来是对栈的一些基础操作进行设定

    设置一些栈操作要用的函数

    比如说
    (下面的S是传进来的栈的指针地址)

    1. 初始化栈:就一个操作,S->top=-1
    2. 入栈:首先,S->top++,然后再S->Elem[S->top]=传进来的元素
    3. 出栈:一个操作,S->top–;,当然要排除掉栈空的情况,即S->top==-1,这种情况就要exit()
    4. 取栈顶元素:我们用返回值返回S->Elem[S->top]就行啦,当然也要排除栈空

    代码如下

    void InitOpter(Opter *S){//初始化运算符栈
        S->top=-1;
    }
    void InitOpnd(Opnd *S){//初始化操作数栈
        S->top=-1;
    }
    
    int PopOpter(Opter *S)//弹出运算符栈
    {
        if(S->top==-1)
        {
            printf("运算符栈为空\n");
            exit(10);
        }
        S->top--;
        return 1;
    }
    
    int PopOpnd(Opnd *S)
    {
        if(S->top==-1)
        {
            printf("运算符栈为空\n");
            exit(11);
        }
        S->top--;
        return 1;
    }
    
    int PushOpter(Opter* S,char ch)
    {
        if(S->top==Stack_Size-1)
        {
            printf("运算符栈满\n");
            exit(12);
        }
        S->top++;
        S->Elem[S->top]=ch;
        return 1;
    }
    
    int PushOpnd(Opnd* S,double ch)//入操作数栈
    {
        if(S->top==Stack_Size-1)
        {
            printf("运算符栈满\n");
            exit(13);
        }
        S->top++;
        S->Elem[S->top]=ch;
        return 1;
    }
    
    char GetOpter(Opter *S)//获取运算符栈的栈顶元素,注意区分返回值类型
    {
        if(S->top==-1)
        {
            printf("运算符栈为空\n");
            exit(17);
        }
        return S->Elem[S->top];
    }
    
    double GetOpnd(Opnd *S)
    {
        if(S->top==-1)
        {
            printf("操作数栈为空\n");
            exit(18);
        }
        return S->Elem[S->top];
    }
    

    有了这些基本工具,接下来是计算函数

    计算函数

    double Calc(double a,double b,char opt)//计算函数,传入两个数以及一个运算符
    {
        double T;   //T用于存放计算得出的结果
        if(opt=='+') T=a+b;
        if(opt=='-') T=a-b;
        if(opt=='*') T=a*b;
        if(opt=='/')     //要防止发生除0错误
        {
            if(fabs(b)<0.00001)
            {
                printf("发生除0错误\n");
                exit(15);
            }
            T=a/b;
        }
        printf("中间过程输出:  %.2lf %c %.2lf = %.2lf\n",a,opt,b,T);
        return T;    //返回得到的结果
    }
    

    在程序执行过程中,我们需要比较两个运算符的优先级来进行计算,所以我们需要创建一个比较函数

    比较函数

    int change(char ch)
    {
        switch(ch)
        {
        case '+':
            return 0;
        case '-':
            return 1;
        case '*':
            return 2;
        case '/':
            return 3;
        case '(':
            return 4;
        case ')':
            return 5;
        case '#':
            return 6;
        }
    }
    
    int Compare(char ch1,char ch2)
    {
        if(cmp[change(ch1)][change(ch2)]=='?'){
            printf("输入表达式错误");
            exit(16);
        }
        return cmp[change(ch1)][change(ch2)];
    }
    

    将运算符转变为优先级比较的数组的下标,通过查阅优先级比较数组中对应的结果,再传给函数,其中change函数就是起到查阅的作用

    检查是否输入多余字符

    我们可能输入表达式的时候会多输入了一些不在范围内的字符,这就需要一个检查函数来排查

    int Check(char *S,int len)//检查函数,记得考虑输入带小数点的数字的情况
    {
        int i;
        for(i=0;i<len;i++){
            if(S[i]>='0'&&S[i]<='9')continue;
            if(S[i]=='('||S[i]==')'||S[i]=='*'||S[i]=='/'||S[i]=='+'||S[i]=='-'||S[i]=='.')continue;
            return 0;
        }
        return 1;
    }
    

    有了上面的这些函数,我们就可以在主函数中进行调试了,我们一些具体的运算操作也是要在主函数中实现的

    主函数该怎么写

    我们直接在代码中进行解释
    代码如下

    int main()
    {
        char a[1000],b[1000];         //创建两个数组,a是用来存输入的表达式的,b是用来存操作数的
        
        int len;        //len为输入表达式的长度,通过strlen求得
        Opter S;    //创建一个运算符栈
        Opnd N;    //创建一个操作数栈
        InitOpnd(&N);   //初始化操作数栈
        InitOpter(&S);   //初始化运算符栈
        
        PushOpter(&S,'#');  
         //注意这里,我们事先在运算符栈中压入一个'#',在输入表达式后,在表达式数组中最后一个位置也设为'#',
         //之后在运算结束时这两个#会相见,比较函数返回'=',使得最终的运算结束
         
        printf("输入表达式:\n");
        scanf("%s",a);    //输入表达式,注意这里a不用取地址符&,因为数组其实就是一个地址,它保留的是数组第一个元素的首地址,a其实就是&a[0]
        
        len=strlen(a);   //求输入的表达式的长度,并打印出来
        printf("字符长度为%d\n",len);
        
        if(Check(a,len)==0)   //检查是否多输入了一些奇奇怪怪的东西
        {
            printf("输入中存在多余字符\n");
            exit(19);
        }
        
        int i,j=0,k=0;
        double x,y;  //x,y是从操作数中取出的两个即将用于计算的数
        a[len]='#';  //注意
        for(i=0;i<=len;i++)  //遍历我们输入的表达式
        {
            if((a[i]>='0'&&a[i]<='9')||a[i]=='.')//如果为数字
            {
                b[k++]=a[i];//将数字存入数组b中,注意此时数字仍为字符
                j=1;
                continue;  //在该循环下其余部分都不做了,直接进入下一次xunh
            }
            if(j)//条件成功即遇到了运算字符,将操作数压入操作数栈中
            {
                //此时数组b已经有了一个或者几个数字在里面,需要加一个'\0'使其成为字符串
                //再通过atof函数使其由字符型变为双精度型,然后加入操作数栈中进行相应运算
                b[k]='\0';
                PushOpnd(&N,atof(b));//atof函数可以使char变为double
                j=0;
                k=0;  //k置零为下一次计数做准备
            }
            switch(Compare(GetOpter(&S),a[i]))//比较运算符栈的栈顶运算符top和运算符a[i]的优先级
            { //底下的部分我们按照之前给的规则来写
         
            case '<'://即top<a[i],则将a[i]直接入栈Opter
                PushOpter(&S,a[i]);
                break;
            case'=':
                PopOpter(&S);
                break;
            case'>':
            //当为‘>'的情况,即需要进行运算,先取操作数栈中最上面的两个元素
                y=GetOpnd(&N),PopOpnd(&N);
                x=GetOpnd(&N),PopOpnd(&N);
                //然后将计算结果压入操作数栈中
                PushOpnd(&N,Calc(x,y,GetOpter(&S)));
                //已经用过的运算符就废掉了,弹出!!!
                PopOpter(&S);
                
                i--;//这句是为了重新把反括号入栈,使之与左括号配对,否则会造成左括号多余出来
                break;
            }
        }
        double answer=GetOpnd(&N);//最终操作数栈中的数就是我们想要的结果
            printf("最终结果为%.2lf",answer);
            return 0;
    
    }
    
    
    
    

    那么用算符优先法对算术表达式求值的程序就算是写完啦

    源程序调试

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    
    #define Stack_Size 1000
    
    char cmp[7][8]= {">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=?",">>>>?>>","<<<<<?="};
    
    typedef struct{//定义一个运算符栈
        char Elem[Stack_Size];
        int top;
    }Opter;
    
    typedef struct{//定义一个操作数栈
        double Elem[Stack_Size];
        int top;
    }Opnd;
    
    
    
    void InitOpter(Opter *S){//初始化运算符栈
        S->top=-1;
    }
    void InitOpnd(Opnd *S){//初始化操作数栈
        S->top=-1;
    }
    
    int PopOpter(Opter *S)//弹出运算符栈
    {
        if(S->top==-1)
        {
            printf("运算符栈为空\n");
            exit(10);
        }
        S->top--;
        return 1;
    }
    
    int PopOpnd(Opnd *S)
    {
        if(S->top==-1)
        {
            printf("运算符栈为空\n");
            exit(11);
        }
        S->top--;
        return 1;
    }
    
    int PushOpter(Opter* S,char ch)
    {
        if(S->top==Stack_Size-1)
        {
            printf("运算符栈满\n");
            exit(12);
        }
        S->top++;
        S->Elem[S->top]=ch;
        return 1;
    }
    
    int PushOpnd(Opnd* S,double ch)//入操作数栈
    {
        if(S->top==Stack_Size-1)
        {
            printf("运算符栈满\n");
            exit(13);
        }
        S->top++;
        S->Elem[S->top]=ch;
        return 1;
    }
    
    char GetOpter(Opter *S)//获取运算符栈的栈顶元素
    {
        if(S->top==-1)
        {
            printf("运算符栈为空\n");
            exit(17);
        }
        return S->Elem[S->top];
    }
    
    double GetOpnd(Opnd *S)
    {
        if(S->top==-1)
        {
            printf("操作数栈为空\n");
            exit(18);
        }
        return S->Elem[S->top];
    }
    
    double Calc(double a,double b,char opt)//计算函数,传入两个数以及一个运算符
    {
        double T;   //T用于存放计算得出的结果
        if(opt=='+') T=a+b;
        if(opt=='-') T=a-b;
        if(opt=='*') T=a*b;
        if(opt=='/')     //要防止发生除0错误
        {
            if(fabs(b)<0.00001)
            {
                printf("发生除0错误\n");
                exit(15);
            }
            T=a/b;
        }
        printf("中间过程输出:  %.2lf %c %.2lf = %.2lf\n",a,opt,b,T);
        return T;    //返回得到的结果
    }
    
    int change(char ch)
    {
        switch(ch)
        {
        case '+':
            return 0;
        case '-':
            return 1;
        case '*':
            return 2;
        case '/':
            return 3;
        case '(':
            return 4;
        case ')':
            return 5;
        case '#':
            return 6;
        }
    }
    
    int Compare(char ch1,char ch2)
    {
        if(cmp[change(ch1)][change(ch2)]=='?'){
            printf("输入表达式错误");
            exit(16);
        }
        return cmp[change(ch1)][change(ch2)];
    }
    
    int Check(char *S,int len)//检查函数,记得考虑输入带小数点的数字的情况
    {
        int i;
        for(i=0;i<len;i++){
            if(S[i]>='0'&&S[i]<='9')continue;
            if(S[i]=='('||S[i]==')'||S[i]=='*'||S[i]=='/'||S[i]=='+'||S[i]=='-'||S[i]=='.')continue;
            return 0;
        }
        return 1;
    }
    
    int main()
    {
        char a[1000],b[1000];         //创建两个数组,a是用来存输入的表达式的,b是用来存操作数的
    
        int len;        //len为输入表达式的长度,通过strlen求得
        Opter S;    //创建一个运算符栈
        Opnd N;    //创建一个操作数栈
        InitOpnd(&N);   //初始化操作数栈
        InitOpter(&S);   //初始化运算符栈
    
        PushOpter(&S,'#');
         //注意这里,我们事先在运算符栈中压入一个'#',在输入表达式后,在表达式数组中最后一个位置也设为'#',
         //之后在运算结束时这两个#会相见,比较函数返回'=',使得最终的运算结束
    
        printf("输入表达式:\n");
        scanf("%s",a);    //输入表达式,注意这里a不用取地址符&,因为数组其实就是一个地址,它保留的是数组第一个元素的首地址,a其实就是&a[0]
    
        len=strlen(a);   //求输入的表达式的长度,并打印出来
        printf("字符长度为%d\n",len);
    
        if(Check(a,len)==0)   //检查是否多输入了一些奇奇怪怪的东西
        {
            printf("输入中存在多余字符\n");
            exit(19);
        }
    
        int i,j=0,k=0;
        double x,y;  //x,y是从操作数中取出的两个即将用于计算的数
        a[len]='#';  //注意
        for(i=0;i<=len;i++)  //遍历我们输入的表达式
        {
            if((a[i]>='0'&&a[i]<='9')||a[i]=='.')//如果为数字
            {
                b[k++]=a[i];//将数字存入数组b中,注意此时数字仍为字符
                j=1;
                continue;  //在该循环下其余部分都不做了,直接进入下一次xunh
            }
            if(j)//条件成功即遇到了运算字符,将操作数压入操作数栈中
            {
                //此时数组b已经有了一个或者几个数字在里面,需要加一个'\0'使其成为字符串
                //再通过atof函数使其由字符型变为双精度型,然后加入操作数栈中进行相应运算
                b[k]='\0';
                PushOpnd(&N,atof(b));//atof函数可以使char变为double
                j=0;
                k=0;  //k置零为下一次计数做准备
            }
            switch(Compare(GetOpter(&S),a[i]))//比较运算符栈的栈顶运算符top和运算符a[i]的优先级
            { //底下的部分我们按照之前给的规则来写
    
            case '<'://即top<a[i],则将a[i]直接入栈Opter
                PushOpter(&S,a[i]);
                break;
            case'=':
                PopOpter(&S);
                break;
            case'>':
            //当为‘>'的情况,即需要进行运算,先取操作数栈中最上面的两个元素
                y=GetOpnd(&N),PopOpnd(&N);
                x=GetOpnd(&N),PopOpnd(&N);
                //然后将计算结果压入操作数栈中
                PushOpnd(&N,Calc(x,y,GetOpter(&S)));
                //已经用过的运算符就废掉了,弹出!!!
                PopOpter(&S);
    
                i--;//这句是为了重新把反括号入栈,使之与左括号配对,否则会造成左括号多余出来
                break;
            }
        }
        double answer=GetOpnd(&N);//最终操作数栈中的数就是我们想要的结果
            printf("最终结果为%.2lf",answer);
            return 0;
    
    }
    

    调试结果
    在这里插入图片描述
    NICE!!!

    展开全文
  • 问题描述:设计一个程序,演示用算符优先法对算术表达式求值的过程。利用算符优先关系,实现对算术四则混合运算表达式的求值。 (1)输入的形式:表达式,例如2*(3+4)# 包含的运算符只能有’+’ 、’-’ 、’’ 、’...

    一、实验目的
    1.掌握栈的存储表示和实现
    2.掌握栈的基本操作实现。
    3.掌握栈在解决实际问题中的应用。
    二、实验要求
    问题描述:设计一个程序,演示用算符优先法对算术表达式求值的过程。利用算符优先关系,实现对算术四则混合运算表达式的求值。
    (1)输入的形式:表达式,例如2*(3+4)#
    包含的运算符只能有’+’ 、’-’ 、’’ 、’/’ 、’(’、 ‘)’,“#”代表输入结束符;
    (2)输出的形式:运算结果,例如2
    (3+4)=14;
    (3)程序所能达到的功能:对表达式求值并输出。
    三、解题参考思路
    为了实现用栈计算算数表达式的值,需设置两个工作栈:用于存储运算符的栈opter,以及用于存储操作数及中间结果的栈opnd。
    算法基本思想如下:
    (1)首先将操作数栈opnd设为空栈,而将’#‘作为运算符栈opter的栈底元素,这样的目的是判断表达式是否求值完毕。
    (2)依次读入表达式的每个字,表达式须以’#‘结,读入字符若是操作数则入栈opnd,读入字符若是运算符,则将此运算符c与opter的栈顶元素top比较优先级后执行相应的操作,具体操作如下:
    (i)若top的优先级小于c,即top<c,则将c直接入栈opter,并读入下一字符赋值给c;
    (ii)若top的优先级等于c,即top=c,则弹出opter的栈顶元素,并读入下一字符赋值给c,这一步目的是进行括号操作;
    (iii)若top优先级高于c,即top>c,则表明可以计算,此时弹出opnd的栈顶两个元素,并且弹出opter栈顶的的运算符,计算后将结果放入栈opnd中。直至opter的栈顶元素和当前读入的字符均为’#’,此时求值结束。
    算符间的优先关系如下表所示(表来源:严蔚敏《数据结构》):

    表中需要注意的是θ1为opter的栈顶元素,θ2为从表达式中读取的操作符,此优先级表可以用二维数组实现。

    1.int getIndex(char theta)   //获取theta所对应的索引  
    2.{  
    3.    int index = 0;  
    4.    switch (theta)  
    5.    {  
    6.    case '+':
    7.        index = 0;  
    8.        break;  
    9.    case '-':  
    10.        index = 1;  
    11.        break;  
    12.    case '*':  
    13.        index = 2;  
    14.        break;  
    15.    case '/':  
    16.        index = 3;  
    17.        break;  
    18.    case '(':  
    19.        index = 4;  
    20.        break;  
    21.    case ')':  
    22.        index = 5;  
    23.        break;  
    24.    case '#':  
    25.        index = 6;  
    26.    default:break;  
    27.    }  
    28.    return index;  
    29.}  
    30.  
    31.char getPriority(char theta1, char theta2)   //获取theta1与theta2之间的优先级  
    32.{  
    33.    const char priority[][7] =     //算符间的优先级关系  
    34.    {  
    35.        { '>','>','<','<','<','>','>' },  
    36.        { '>','>','<','<','<','>','>' },  
    37.        { '>','>','>','>','<','>','>' },  
    38.        { '>','>','>','>','<','>','>' },  
    39.        { '<','<','<','<','<','=','0' },  
    40.        { '>','>','>','>','0','>','>' },  
    41.        { '<','<','<','<','<','0','=' },  
    42.    };  
    43.  
    44.    int index1 = getIndex(theta1);  
    45.    int index2 = getIndex(theta2);  
    46.    return priority[index1][index2];  
    } 
    
    #include"stdio.h"
    #include"stdlib.h" 
    #include"string.h" 
    #include"math.h"
    #define true 1 
    #define false 0 
    #define OPSETSIZE 8 
    typedef int Status; 
    int getIndex(char theta);
    char getPriority(char theta1, char theta2)   //获取theta1与theta2之间的优先级  
    	{  
    	    const char priority[][7] =     //算符间的优先级关系  
    	    {  
    	        { '>','>','<','<','<','>','>' },  
    	        { '>','>','<','<','<','>','>' },  
    	        { '>','>','>','>','<','>','>' },  
    	        { '>','>','>','>','<','>','>' },  
    	        { '<','<','<','<','<','=','0' },  
    	        { '>','>','>','>','0','>','>' },  
    	        { '<','<','<','<','<','0','=' },  
    	    };  
    	  
    	    int index1 = getIndex(theta1);  
    	    int index2 = getIndex(theta2);  
    	    return priority[index1][index2];  
    	} 
    int getIndex(char theta)   //获取theta所对应的索引  
    	{  
    	    int index = 0;  
    	    switch (theta)  
    	    {  
    	    case '+':
    	        index = 0;  
    	        break;  
    	    case '-':  
    	        index = 1;  
    	        break;  
    	    case '*':  
    	        index = 2;  
    	        break;  
    	    case '/':  
    	        index = 3;  
    	        break;  
    	    case '(':  
    	        index = 4;  
    	        break;  
    	    case ')':  
    	        index = 5;  
    	        break;  
    	    case '#':  
    	        index = 6;  
    	    default:break;  
    	    }  
    	    return index;  
    	}  
    
    typedef struct StackChar
    {//定义链表类型的字符串,用来存储运算的栈 
    	char c;   //数据域 
    	struct StackChar *next; //指针域 
    }SC;       //StackChar类型的结点SC
    
    typedef struct StackFloat
    {//定义链表类型的数组,是用来存储运算数字的栈的 
    	float f; //数据域 
    	struct StackFloat *next; //指针域 
    }SF;       //StackFloat类型的结点SF
    
    SC *Push(SC *s,char c)          //SC类型的指针Push,返回p
    { //压入元素 
    	SC *p=(SC*)malloc(sizeof(SC));  //分配一个SC类型的空间p 
    	p->c=c; //给p的数据域赋值 
    	p->next=s; //把p的指针域指向s 
    	return p; //返回最新的栈顶位置 
    } 
     
    SF *Push(SF *s,float f)        //SF类型的指针Push,返回p
    { //压入元素
    	SF *p=(SF*)malloc(sizeof(SF)); //分配一个SC类型的空间p 
    	p->f=f; //给p的数据域赋值 
    	p->next=s; //把p的指针域指向s 
    	return p; //返回最新的栈顶位置 
    } 
     
    SC *Pop(SC *s)    //SC类型的指针Pop
    {//用来将char类型的操作符栈的栈顶元素弹出栈 
    	SC *q=s;   //临时指针q用来临时保存栈顶元素的位置 
    	s=s->next; //将s指针指向s后面的一个元素 
    	free(q); 
    	return s; 
    } 
     
    SF *Pop(SF *s)      //SF类型的指针Pop
    {//用来将float类型的栈的栈顶元素(被运算的数字)弹出栈 
    	SF *q=s; 
    	s=s->next; 
    	free(q); 
    	return s; 
    } 
     
    float Operate(float a,unsigned char theta, float b)      //计算函数Operate
    {
    	switch(theta)
    	{
    	case '+': return a+b; 
    	case '-': return a-b; 
    	case '*': return a*b; 
    	case '/': return a/b; 
    	default : return 0; 
    	} 
    } 
     
    char OPSET[OPSETSIZE]={'+','-','*','/','(',')','#'}; 
    
    Status In(char Test,char *TestOp)
    {//IN函数用来判定当前元素是否为运算符 
    	int Find=false; 
    	for (int i=0; i< OPSETSIZE; i++)
    	{
    		if(Test == TestOp[i])
    			Find= true; 
    	} 
    	return Find; //如果是运算符返回1(TURE),否则返回0(FALSE) 
    } 
     
    Status ReturnOpOrd(char op,char *TestOp)
    { 
    	for(int i=0; i< OPSETSIZE; i++)
    	{
    		if (op == TestOp[i])
    			return i;
    	}
    }
     
     
     
    float EvaluateExpression(char* MyExpression)//将运算表达式(MyExpression)传入处理函数 
    { 
    	// 算术表达式求值的算符优先算法
    	// 设OPTR和OPND分别为运算符(operator)栈和运算数(operand)栈,OP为运算符集合 
    	SC *OPTR=NULL;       // 运算符栈,字符元素 
    	SF *OPND=NULL;       // 运算数栈,实数元素 
    	char TempData[20]; 
    	float Data,a,b; 
    	char theta,*c,Dr[]={'#','\0'}; 
    	OPTR=Push(OPTR,'#'); //在运算符栈栈底压入"#",当作结束标志位 
    	c=strcat(MyExpression,Dr); //给运算表达式末尾添加Dr[]={'#','\0'} 
    	strcpy(TempData,"\0");  //字符串拷贝函数 
    	while (*c!= '#' || OPTR->c!='#') //只要运算表达式c未循环到末尾(c指向不为末尾的"#"),或则OPTR栈未到栈底 
    	{ 
    		if (!In(*c, OPSET))  //如果当c所指向的不是字符 
    		{ 
    			Dr[0]=*c;              
    			strcat(TempData,Dr);           //字符串连接函数 
    			c++; 
    			if (In(*c, OPSET))
    			{ 
    				Data=atof(TempData);       //atof(ascii to float)字符串转换函数(double),把字符转化为double类型 
    				OPND=Push(OPND, Data);      //操作数压入 
    				strcpy(TempData,"\0"); 
    			} 
    		} 
    		else    // 不是运算符则进栈 
    		{
    			 
    			switch (getPriority(OPTR->c, *c))  //判断当前操作数,和栈顶操作数的优先级大小 
    			{
    			case '<': // 栈顶元素优先级低,当前元素直接进栈 
    				OPTR=Push(OPTR, *c);    
    				c++; 
    				break; 
    			case '=': // 脱括号并接收下一字符 
    				OPTR=Pop(OPTR); 
    				c++; 
    				break; 
    			case '>': // 退栈并将运算结果入栈,
    				theta=OPTR->c;OPTR=Pop(OPTR); 
    				b=OPND->f;OPND=Pop(OPND); 
    				a=OPND->f;OPND=Pop(OPND); 
    				OPND=Push(OPND, Operate(a, theta, b)); 
    				break; 
    			} //switch
    		} 
    	} //while 
    	return OPND->f; 
    } //EvaluateExpression 
     
    int main(void)
    { 
    	char s[128];
    	puts("请输入表达式:"); 
    	gets(s);
    	puts("该表达式的值为:"); 
    	printf("%s\b=%g\n",s,EvaluateExpression(s));
    	system("pause");
    	return 0;
    }
    
    展开全文
  • 设计一个程序,演示用算符优先法对算术表达式求值的过程。 基本要求:以字符序列的形式从终端输入语法正确的、不含变量的整数表达式。利用教科书表3.1给出的算符优先关系,实现对算术四则混合运算表达式的求值,并...
  • 为了实现算符优先算法,需要两个工作栈,一个用来存放操作数(CZS),一个用来存放运算符(YSF)。 算法的基本思想: (1)首先置操作数栈、运算符栈均为空,将‘#’压入运算符栈。 (2)依次读入表达式中的每...

    本文转载自:https://blog.csdn.net/qianchangdiyin/article/details/49513213

    为了简化问题,我们只考虑+、-、*、/四种运算,他们的优先级规则:
    (1)先乘除,后加减
    (2)从左算到右
    (3)先括号内,再括号外

    这里写图片描述

    为了实现算符优先算法,需要两个工作栈,一个用来存放操作数(CZS),一个用来存放运算符(YSF)。
    算法的基本思想:
    (1)首先置操作数栈、运算符栈均为空,将‘#’压入运算符栈。
    (2)依次读入表达式中的每个字符,如果是操作数则直接压入操作数栈(当然,操作数可能不是一位数,可以先用字符串保存每次读入的字符,再转为Int型,压入操作数栈)。如果是运算符,则需要与运算符栈顶元素比较。若运算符栈顶字符的优先级高于当前预算符,出现句柄,需要从操作数栈中弹出两个操作数,从运算符栈顶弹出一个运算符,进行运算后将结果压入操作数栈,注意,此时并没有读入下一个字符,还是用当前字符和栈顶字符比较;若运算符栈顶字符优先级小于当前字符,则直接将当前字符压入运算符栈,读入下一个字符;若运算符栈顶字符的优先级等于当前字符,如’(‘和’)’,则运算符栈弹出一个元素,读入下一个字符。

    # include<stdio.h>
    # include<stdlib.h>
    # include<string.h>
    
    # define MAX 100
    
    //运算符
    typedef struct{
        char data[MAX];
        int top;
    }Operator;
    
    //操作数
    typedef struct{
        int data[MAX];
        int top;
    }Operand;
    
    int operate(int a,char theta,int b);
    void InitStack(Operator &s);
    void InitStack(Operand &s);
    int Push(Operator &s,char c);
    int Push(Operand &s,int a);
    int Pop(Operator &s);
    int Pop(Operand &s);
    char getTop(Operator &s);
    int getTop(Operand &s);
    char Precede(char a,char b);
    
    int main()
    {
        Operator YSF;//运算符栈
        Operand CZS;//操作数栈
        char num[15];
        InitStack(CZS);
        InitStack(YSF);
        Push(YSF,'#');
        printf("-------四则运算(加减乘除),输入以#号结束--------\n");
        char ch=getchar();
        while(ch!='#'||getTop(YSF)!='#')
        {
            int i=0,a,b,flag=0;
            char theta;
            while(ch>='0'&&ch<='9')
            {
                flag=1;
                num[i++]=ch;
                ch=getchar();
            }
            if(flag)
            {
                num[i]='\0';
                Push(CZS,atoi(num));
            }
            if(ch<'0'||ch>'9')
            {
                switch(Precede(getTop(YSF),ch))
                {
                case '>':
                    theta=getTop(YSF);
                    Pop(YSF);
                    b=getTop(CZS);
                    Pop(CZS);
                    a=getTop(CZS);
                    Pop(CZS);
                    Push(CZS,operate(a,theta,b));
                    break;
                case '=':
                    Pop(YSF);
                    ch=getchar();
                    break;
                case '<':
                    Push(YSF,ch);
                    ch=getchar();
                    break;
                }
            }
        }
        printf("%d\n",getTop(CZS));
        return 0;
    }
    
    int operate(int a,char theta,int b)
    {
        if(theta=='+')
            return a+b;
        else if(theta=='-')
            return a-b;
        else if(theta=='*')
            return a*b;
        else if(theta=='/')
            return a/b;
    }
    
    void InitStack(Operator &s)
    {
        memset(s.data,0,MAX*sizeof(char));
        s.top=0;
    }
    
    void InitStack(Operand &s)
    {
        memset(s.data,0,MAX*sizeof(int));
        s.top=0;
    }
    
    int Push(Operator &s,char c)
    {
        if(s.top>=MAX)
            return 0;
        else
        {
            s.data[s.top]=c;
            s.top++;
            return 1;
        }
    }
    
    int Push(Operand &s,int a)
    {
        if(s.top>=MAX)
            return 0;
        else
        {
            s.data[s.top]=a;
            s.top++;
            return 1;
        }
    }
    
    int Pop(Operator &s)
    {
        if(s.top==0)
            return 0;
        else
        {
            s.top--;
            s.data[s.top]=0;
            return 1;
        }
    }
    
    int Pop(Operand &s)
    {
        if(s.top==0)
            return 0;
        else
        {
            s.top--;
            s.data[s.top]=0;
            return 1;
        }
    }
    
    char getTop(Operator &s)
    {
        return s.data[s.top-1];
    }
    
    int getTop(Operand &s)
    {
        return s.data[s.top-1];
    }
    
    //比较两个运算符的优先级,a运算符在b左边
    char Precede(char a,char b)
    {
        if(a=='+'||a=='-')
        {
            if(b=='+'||b=='-'||b==')'||b=='#')
                return '>';
            else
                return '<';
        }
        else if(a=='*'||a=='/')
        {
            if(b=='(')
                return '<';
            else
                return '>';
        }
        else if(a=='(')
        {
            if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(')
                return '<';
            else if(b==')')
                return '=';
            else
            {
                printf("输入有误");
                return 0;
            }
        }
        else if(a==')')
        {
            if(b=='+'||b=='-'||b=='*'||b=='/'||b==')'||b=='#')
                return '>';
            else if(b=='(')
            {
                printf("输入有误");
                return 0;
            }
        }
        else if(a=='#')
        {
            if(b==')')
            {
                printf("输入有误");
                return 0;
            }
            else if(b=='#')
                return '=';
            else
                return '<';
        }
    }
    
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217

    这里写图片描述

    •                     <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                              <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#csdnc-thumbsup"></use>
                          </svg><span class="name">点赞</span>
                          <span class="count">6</span>
                          </a></li>
                          <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                              <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-csdnc-Collection-G"></use>
                          </svg><span class="name">收藏</span></a></li>
                          <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                              <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-csdnc-fenxiang"></use>
                          </svg>分享</a></li>
                          <!--打赏开始-->
                                                  <!--打赏结束-->
                                                  <li class="tool-item tool-more">
                              <a>
                              <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                              </a>
                              <ul class="more-box">
                                  <li class="item"><a class="article-report">文章举报</a></li>
                              </ul>
                          </li>
                                              </ul>
                  </div>
                              </div>
              <div class="person-messagebox">
                  <div class="left-message"><a href="https://blog.csdn.net/qianchangdiyin">
                      <img src="https://profile.csdnimg.cn/9/6/2/3_qianchangdiyin" class="avatar_pic" username="qianchangdiyin">
                                              <img src="https://g.csdnimg.cn/static/user-reg-year/2x/7.png" class="user-years">
                                      </a></div>
                  <div class="middle-message">
                                          <div class="title"><span class="tit"><a href="https://blog.csdn.net/qianchangdiyin" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">flying_fish_233</a></span>
                                              </div>
                      <div class="text"><span>发布了65 篇原创文章</span> · <span>获赞 25</span> · <span>访问量 6万+</span></div>
                  </div>
                                  <div class="right-message">
                                              <a href="https://im.csdn.net/im/main.html?userName=qianchangdiyin" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                          </a>
                                                              <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                      </div>
                              </div>
                      </div>
      
    展开全文
  • 实验目的 1. 掌握栈的操作特性及其顺序存储和链式存储结构 2. 灵活运用栈解决实际问题。 实验内容 利用栈实现算符优先法进行表达式求值,测试表达式为: 5*(3+2)-6/2# 提示:利用c++的stack容器。
  • 基于运算符栈和运算数栈,利用算符优先法对输入的中缀表达式求值。
  • 算符优先分析

    2018-05-22 21:12:04
    设有文法G[S]:S→SaF | F F→FbP | P P→c | d (1) 构造G[S]的算符优先关系表 (2) 分别给出cadbdac# 和 dbcabc# 的分析过程
  • c++语言 编译原理 赋值语句的语法分析程序 算符优先法 有详细的出错提示
  • 1、 实验目的:采用算符优先分析对表达式进行分析,掌握算符优先分析的基本原理和实现过程。 2、 实验要求: 文法:无二义性的算术表达式的文法 (1)把词法分析作为语法分析的子程序实现(5分) (2)独立的...
  • 利用算符优先法分析源程序,输入一个分析式以#结束,输出分析表
  • 编译原理 算符优先法文法分析 由于水平有限,这里就不写原理了,请参考书《编译原理》(第3版)——清华大学出版社。 书中相关内容为第110页5.3.3节到第117页。其中FIRSTVT集和LASTVT集是根据第114页的简单关系图形...
  • 输入为表达式,以‘#’结尾 例如:2+3*(33-23) +5/4# #include #include #include #include #include #include using namespace std;...char ch[10]={'+','-','*','/','(',')','#'};...int compare[7][7]=
  • 自下而上的分析——算符优先分析

    万次阅读 多人点赞 2018-05-13 19:19:42
     算符优先分析(Operator Precedence Parse)是仿效四则运算的计算过程而构造的一种语法分析方法。算符优先分析的关键是比较两个相继出现的终结符的优先级而决定应采取的动作。  优点:简单,有效,适合表达式...
  • 算符优先分析不是一种规范规约,但是该方法特别有利于表达式分析,宜于手工实现。 算符优先分析和计算的过程相同,由此判断一个符号的左右符号优先级,从而确定是否可以规约。 对于任何两个可能相继出现的终结...
  • 算符优先法” : 比如说对于1+2*3+2-3/5我们人为计算的时候,肯定是先计算*/再计算+-,现在让计算机计算这个表达式,那么必然要模拟这种求值的先后顺序,假设两个从左向右相邻的运算符分别为θ1、θ2,则他们的...
  • 根据某一文法编制调试语法分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对自下而上的算符优先分析的理解。附有流程图。
  • 表达式求值,算符优先法。利用函数模板写的,突破了一般的只能运算个位数的算法。
  • 简单表达式求值——算符优先法

    千次阅读 2012-11-18 16:49:01
    周五加班的时候,在九度oj上练习了一道简单表达式求值的题目,用到了“算符优先法”,这里简单的记录一下 题目 题目描述: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。 输入: ...
  • 语法分析程序可以根据个人的掌握情况选用常见的几种语法分析方法:递归下降分析方法、LL(1)预测分析算符优先分析、LR分析等方法中的任何一种来实现,也可以选用不同的方法来分析不同的语法成分,最后再综合起来...
  • 数据结构-算术表达式-算符优先法

    千次阅读 2015-10-23 11:45:54
    /*判断算符优先关系*/ char judge( char a, char b) { switch (a) { case '+' : if (b == '+' || b == '-' || b == ')' || b == '#' ) { return '>' ; } else { return ' ; ...
  • 实验3《算符优先分析设计与实现》 一、实验目的   加深对语法分析器工作过程的理解;加强对算符优先分析实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对...
  • 可编辑范本 }可编辑范本 } 可编辑范本 实习报告 题目 设计一个演示用运算优先法对算数表达式求值过程的程序 班级 姓名 学号 完成日期 一 需求分析 1建立运算数栈SqStack和运算符栈SqStack2辅助分析算符有限关系....
  • 算符优先分析-思路方法在这里

    千次阅读 多人点赞 2020-05-16 20:48:28
    3.构造并输出算符优先分析表,判断是否为算符优先文法,若不是提示无法进行分析; 4.任意输入一个输入串,可得到成功的分析或错误的提示,输出其分析过程或打印语法 分析树。 实验运行结果 算符优先文法的特点: ...
  • 编译原理 算符优先文法 实验报告 代码 运行成功////////////
  • (Python实现,注释详细)直接输入:3+4*5,一般的...(1)第一阶段,运用算符优先分析算法完成计算器中对算术表达式的语法分析; (2)第二阶段,设计属性文法,改造第一阶段的程序,完成算术表达式的计算和相关的输出。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,596
精华内容 1,438
关键字:

算符优先法