中缀表达式求值

描述

人们熟悉的四则运算表达式称为中缀表达式,例如(23+34*45/(5+6+7))。在程序设计语言中,可以利用堆栈的方法把中缀表达式转换成保值的后缀表达式(又称逆波兰表示法),并最终变为计算机可以直接执行的指令,得到表达式的值。
给定一个中缀表达式,编写程序,利用堆栈的方法,计算表达式的值。

输入

第一行为测试数据的组数N
接下来的N行,每行是一个中缀表达式。表达式中只含数字、四则运算符和圆括号,操作数都是正整数,数和运算符、括号之间没有空格。中缀表达式的字符串长度不超过600。

输出

对每一组测试数据输出一行,为表达式的值

解法

该问题可以转换为两个子问题:

1、将中缀表达式转换为后缀表达式

2、利用栈对后缀表达式求值

中缀表达式转后缀表达式

算法: 可以使用栈来完成中缀表达式到后缀表达式的转换

1、栈stack[]用来存储操作符,top指向栈顶,但不存储元素,top=0表示栈为空

2、从左向右遍历中缀表达式

  a.如果遇到的是操作数num,则直接输出到后缀表达式

  b.如果遇到的是操作符op,则有几种情况:

    b.1.如果op==')',则依次弹出栈顶直到弹出'(',但'('不输出到后缀表达式

    b.2:如果op=='(',则直接入栈

    b.3:如果栈为空,则直接入栈

    b.4:如果op的优先级高于栈顶操作符的优先级,则入栈

    b.5:如果op的优先级低于或等于栈顶操作符的优先级,则依次弹出栈顶直到op的优先级高于栈顶操作符的优先级(或栈为空),再将op入栈

3、遍历完时,如果栈仍不为空,则依次弹出栈顶直到栈为空

具体的代码如下:

 1 int mycmp(char a, char b) {

 2     if(b == '(')

 3         return 1;//左括号直接入栈

 4     else if((b == '*' || b == '/') &&(a == '+' || a == '-' || a == '('))

 5         return 1;//*、/优先级高于+、-、(,入栈

 6     else if((b == '+' || b == '-') && (a == '('))

 7         return 1;//+、-优先级高于(,入栈

 8     else

 9         return 0;

10 }

11 

12 /*中缀表达式转后缀表达式

13  中缀表达式之间无分割

14  后缀表达式操作数、操作符之间用空格分割,便于区分不同操作数*/

15 void infix_to_suffix(char* infix, char* suffix) {

16     int i, k, j=0, top=0;

17     char stack[1000];//存储运算符的栈

18 

19     for(i=0; infix[i]!='\0'; i++) {

20         if(infix[i] >= '0' && infix[i] <= '9') {

21             suffix[j++] = infix[i];//操作数则直接输出

22         } else {

23             if(i != 0 && infix[i-1] >= '0' && infix[i-1] <= '9') {

24                 suffix[j++] = ' ';//操作数后补充空格分割

25             }

26             if(infix[i] == ')') {

27                 //遇到右括号则一直弹出直到左括号,但左括号不输出

28                 while(stack[top-1] != '(') {

29                     suffix[j++] = stack[--top];

30                     suffix[j++] = ' ';

31                 }

32                 top--;

33             } else if(top == 0 || mycmp(stack[top-1], infix[i])) {

34                 //栈为空或当前操作符的优先级高于栈顶操作符,当前操作符入栈

35                 stack[top++] = infix[i];

36             } else {

37                 //当前操作符优先级等于或低于栈顶操作符则弹出栈顶

38                 while(!mycmp(stack[top-1], infix[i])) {

39                     suffix[j++] = stack[--top];

40                     suffix[j++] = ' ';

41                     if(top == 0)

42                         break;

43                 }

44                 stack[top++] = infix[i];//当前操作符入栈

45             }

46         }

47     }

48     //补充空格分割

49     if(suffix[j-1] != ' ') {

50         suffix[j++] = ' ';

51     }

52     //如果操作符栈不为空,弹出所有操作符

53     while(top != 0) {

54         suffix[j++] = stack[--top];

55         suffix[j++] = ' ';

56     }

57     suffix[j] = '\0';

58 }

 

利用栈对后缀表达式求值

算法:

1、栈stack[]用来存储操作数,top指向栈顶,但不存储元素,top=0表示栈为空,

2、从左向右依次遍历后缀表达式

   a.如果遇到的是操作数num,则直接将num入栈,即stack[top++]=num

   b.如果遇到的是操作符op,则取出依次取出栈顶的两个元素stack[top-2]和stack[top-1],计算stack[top-2] op stack[top-1]的结果,并将结果入栈

3、遍历结束时,stack[top-1]即为后缀表达式求值结果

具体的C语言代码如下:

 1 /*后缀表达式求值*/

 2 int suffix_value(char* suffix) {

 3     int i, j;

 4     char op;

 5     int stack[1000];

 6     int top = 0, value = 0;

 7     for(i=0; suffix[i] != '\0'; i++) {

 8         if(suffix[i] >= '0' && suffix[i] <= '9') {

 9             value = value*10 + suffix[i] - '0';

10         } else if(suffix[i] == ' ') {

11             //操作数入栈

12             stack[top++] = value;

13             value = 0;

14         } else {

15             //根据操作符,对栈顶两个操作数进行计算并得到结果

16             switch(suffix[i]) {

17                 case '+': value = stack[top-2] + stack[top-1];break;

18                 case '-': value = stack[top-2] - stack[top-1];break;

19                 case '*': value = stack[top-2] * stack[top-1];break;

20                 case '/': value = stack[top-2] / stack[top-1];break;

21                 default: break;

22             }

23             top -= 2;

24         }

25     }

26 

27     return stack[0];

28 }

 

至此,中缀表达式求值的主程序如下:

 1 int main() {

 2     int n;

 3     char infix[1000], suffix[1000];//infix中缀表达式,suffix后缀表达式

 4     

 5     scanf("%d\n", &n);

 6     while(n--) {

 7         gets(infix);

 8         infix_to_suffix(infix, suffix);    

 9         printf("%d\n", suffix_value(suffix));

10     }

11 

12     return 0;

13 }

 

 

你可能感兴趣的:(表达式)