中缀表达式的值——解题报告

来源:互联网 发布:淘宝男装服装 编辑:程序博客网 时间:2024/05/22 02:14

    去年的大连市赛上貌似就有这个类型的题,当时没做下来,之后听学长讲过,明白思路但是没有动手一试。所以就借着这个题,过一下。

    题目链接 D1092:中缀表达式的值

   在程序设计语言中,可以利用堆栈的方法把中缀表达式转换成保值的后缀表达式(又称逆波兰表示法),并最终变为计算机可以直接执行的指令,得到表达式的值。

  例子: 3+5*8  =》 3 5 8*+;    (3+5)*8  =》3 5 + 8 *;    (23+34*45/(5+6+7)) =》 23 34 45 *5 6 +7 +/+;

 注意问题:①问题考虑全面,不要出现栈为空还在判栈顶元素等情况(Runtime Error,很悲催,因为这个多交了两次)

                     ②中缀变后缀时,优先级相同时从栈中去元素

 

 

 

代码如下:

 

#include <stdio.h>#include <stack>#include <string.h>#define MAX 700using namespace std;char str[MAX], record[MAX];//str,record分别存放中缀和后缀表达式stack<char> s;stack<int> sta;int priority(char a){ //定义优先级    switch(a){        case '(': return 0;        case '+':        case '-': return 1;        case '*':        case '/': return 2;        case ')': return 3;    }    return -1;}bool judgenum(char a){ //判断是否为数字    if(a>='0'&&a<='9'){        return true;    }    return false;}int calnum(char op, int a, int b){ //计算规则    switch(op){        case '+': return a+b;        case '-': return a-b;        case '*': return a*b;        case '/': return a/b;    }}void change(char *str, char *record){ //中缀表达式转为后缀,返回后缀表达式的长度    int len = strlen(str);    int length = 0;    for(int i=0; i<len; i++){        if(judgenum(str[i])){ //数字            record[length] = str[i];   length++;            if(i+1<len&&!judgenum(str[i+1])){ //下一个不是数字,加空格                record[length] = ' ';  length++;            }        }        else{ //操作符            if(s.empty()){ //栈为空,直接入栈                s.push(str[i]);            }            else{                if(str[i]==')'){ //弹出栈中的元素直到遇到“(”;                    while(s.top()!='('){                          record[length] = s.top(); length++;                          s.pop();                        }                          s.pop(); //弹出左括号                }                else if(str[i]=='('){                        s.push(str[i]);                        }                else if(priority(s.top())<priority(str[i])){                    s.push(str[i]);                }                else{                    while(!s.empty()&&priority(s.top())>=priority(str[i])){ //优先级相同,则弹出; !s.empty()                        record[length] = s.top(); length++;                        s.pop();                    }                    s.push(str[i]);                }            }        }    }    while(!s.empty()){ //容易忽略了这种情况        record[length] = s.top();        length++; s.pop();    }}int calrecord(char *record){ //利用后缀表达式计算表达式的值    int len = strlen(record);    int i=0;    int result, a, b;    int num = 0;    while(i<len){        if(record[i]==' '){ //空格        }        else if(judgenum(record[i])){ //数字            num = num*10+record[i]-'0';            if(i+1<len&&!judgenum(record[i+1])){                sta.push(num);                num = 0;            }        }        else{ //操作符            b = sta.top(); sta.pop();            a = sta.top(); sta.pop();            sta.push(calnum(record[i], a, b));        }        i++;    }    result = sta.top();  sta.pop();    return result;}void show(char *record){  printf("%s\n", record);}int main(){    freopen("a.txt", "r",stdin);    int n;    scanf("%d", &n);    while(n--){        memset(str, 0, sizeof(str));        memset(record, 0, sizeof(record));        scanf("%s", str);        change(str, record);        show(record);        printf("%d\n", calrecord(record));    }    return 0;}

	
				
		
原创粉丝点击