后缀表达式(仅含乘与加)的计算(含C代码),栈

问题描述

给定一个只含加法和乘法的后缀表达式,请计算出它的值。表达式长度<=1000,各结果不超过int范围。

输入第一行包含一个整数T,代表一共有T组测试样例。
每组测试样例占1行,每相邻两项之间由一个空格隔开,最后一项后只有换行符,没有空格。输入保证合理。输出对于每组样例,输出一行(不包含引号)“Case t: ans”,其中t代表样例编号,由1开始,ans是运算的结果。样例输入

2
1 2 + 3 * 4 +
1 1 + 1 1 + *

样例输出

Case 1: 13
Case 2: 4






总论:后缀表达式(仅含乘与加)的计算:首先把问题模块化,可以分解成以下问题:数据的读取,数据的甄别,数据的计算。对于后缀表达式的计算,其思想为从式子中读取字符,遇到数字则压入数字栈,遇到运算符则从栈中取出两个数字计算,再把计算结果压入栈,直到遍历所有字符。

具体实现:首先开辟一个顺序栈,包括数组,栈顶指示top,其次编写入栈,出栈的函数。之后需要判断读入的字符是数字还是运算符(决定入栈还是从栈中取数),编写一个判断数字函数。然后就是计算了,计算函数包含三个参数,两个运算数,一个运算符,分别是数值型和字符型数据。到这里,大体的框架完成了一半,下面是一些具体问题。

具体问题及其处理:

问题1:整体的运算框架问题?

答:读入数据组数,用一个for循环处理多组数据,之后读入字符串,这里用gets函数。计算出长度,再用一个for循环遍历每一个字符,以便运算。

问题2:空格的处理问题?

答:关于空格的处理,这里用了一个if判断和continue语句,一旦是空格则返回++,读取下一个字符。

问题3:如何解决非各位数字的读取问题?

答:这里采用了一个while循环,利用is_number函数判断,连续读入数字字符,也就是说对后缀表达式遍历的进程不仅取决于上层for循环,此处的while循环也会加速遍历进程,这就需要注意上层for循环中的循环变量随while循环次数而增加,这就需要重新开辟一个变量代替for中的循环变量进行++。

问题4:如何解决计算问题?

答:for循环对后缀字符串的遍历内层是一个is_number的判断,问题三是关于数字的问题,此处是关于运算符的问题,如何根据读取的运算符进行运算。注意到,这里的运算符都是双目运算符,也就是意味着需要从数据栈中取出两个数字进行运算,利用计算函数进行计算,注意,一定要把运算结果压入栈中!

问题5:top的初始化问题

注意到,处理完一组数据后,top此时应该为-1,但是为了保险起见,最好还是在第二个for循环之前对top重新初始化。

下边是具体的代码实现。

#include <stdio.h>
#include <string.h>
int stack[1000];
int top = -1;

char read_string[1000];

int is_number(char c)
{
    return c >= '0' && c <= '9';
}
void push_stack(int k)
{
    stack[++top]=k;
}
int pop_stack()
{
    if(top < 0)
    {
        printf("error");
    }
    else
    {
        return stack[top--];
    }
}
int calc(int a,int b,char c)
{
    if(c=='+')return a+b;
    if(c=='*')return a*b;
}
int main()
{
    int i,j,k,n,slen,t;
    scanf("%d ",&n);
    for(i = 1;i <= n;i++)
    {
        top = -1;
        gets(read_string);
        slen = strlen(read_string);
        for(t = 0;t < slen;t++)
        {
            if (read_string[t] == ' ') continue;
            if(is_number(read_string[t]))
            {
                j = t;
                k = 0;
                while(j < slen&&is_number(read_string[j]))
                {
                    k = k*10+(read_string[j]-'0');
                    j++;
                }
                t = j-1;
                push_stack(k);
            }
            else
            {
                int b = pop_stack();
                int a = pop_stack();
                push_stack(calc(a,b,read_string[t]));
            }
        }
        printf("Case %d: %d\n", i, pop_stack());
    }
}

 

posted @ 2017-04-10 15:30  visionshao  阅读(881)  评论(0)    收藏  举报