用栈求算术表达式的值

青春壹個敷衍的年華 提交于 2019-11-28 16:17:33
  • 题目:1 将中缀表达式转换为后缀表达式
  • 2 求后缀表达式的值
#include<stdio.h>

#define MaxSize 100

struct
{
    char data[MaxSize];
    int top;  //栈顶指针
}op;  //定义运算符栈

struct
{
    float data[MaxSize];
    int top;
}st;  //定义数值栈

void trans(char exp[],char postexp[])
{
    int i = 0;
    int j = 0;
    char ch;
    op.top = -1;  //栈顶指针初始化为-1
    ch = exp[i];
    i++;

    while (ch != '\0')
    {
        switch (ch)
        {
        case '(':  //判定为左括号 直接入栈
            op.top++;
            op.data[op.top] = ch;
            break;
        case ')':
            while (op.data[op.top] != '(')
            {
                postexp[j] = op.data[op.top];
                op.top--;
                j++;
            }
            op.top--;  //左括号也出栈 但不输出
            break;
        case '+':
        case '-':
            //为 + 或者 - 时候,优先级不大于栈顶任何运算符的优先级 直到 )
            while (op.top != -1 && op.data[op.top] != '(')
            {
                postexp[j] = op.data[op.top];
                j++;
                op.top--;
            }
            op.top++;
            op.data[op.top] = ch;
            break;
        case '*':
        case '/':
            //为 * 或者是 / 时, 其优先级不大于栈顶为 * 或者为 /的优先级 直到 (
            while (op.top != -1 && op.data[op.top] != '('
                && (op.data[op.top] == '*' || op.data[op.top] == '/'))
            {
                //将栈顶运算符弹出并输出
                postexp[j] = op.data[op.top];
                j++;
                op.top--;
            }
            //该运算符的优先级大于栈顶运算符的优先级 直接压栈
            op.top++;
            op.data[op.top] = ch;
            break;
        case ' ':  //过滤掉空格
            break;  
        default:
            while (ch >= '0' && ch <= '9') //判定为数字
            {
                postexp[j] = ch;
                j++;
                ch = exp[i];
                i++;
            }
            i--;
            postexp[j] = '#';  //用#标识一个数值串结束
            j++;
            break;
        }
        ch = exp[i];
        i++;
    }

    while (op.top != -1)  //此时exp扫描完毕 栈不空时出栈并存放到postexp
    {
        postexp[j] = op.data[op.top];
        j++;
        op.top--;
    }
    postexp[j] = '\0';  //添加结束标识符
}

//后缀表达式的求值过程
float Compvalue(char postexp[])
{
    char ch;
    float d;
    int i = 0;
    ch = postexp[i];
    i++;
    st.top = -1;
    while (ch != '\0')
    {
        switch (ch)
        {
        case '+':
            st.data[st.top - 1] = st.data[st.top - 1] + st.data[st.top];
            st.top = st.top - 1;
            break;
        case '-':
            st.data[st.top - 1] = st.data[st.top - 1] - st.data[st.top];
            st.top = st.top - 1;
            break;
        case '*':
            st.data[st.top - 1] = st.data[st.top] * st.data[st.top - 1];
            st.top = st.top - 1;
            break;
        case '/':
            if (st.data[st.top] != 0)
            {
                st.data[st.top - 1] = st.data[st.top - 1] / st.data[st.top];
                st.top = st.top - 1;
            }
            else
            {
                printf("除数为0.\n");
                return 0.0;
            }
            break;
        default:
            d = 0;
            while (ch >= '0' && ch <= '9')
            {
                d = d * 10 + ch - '0';
                ch = postexp[i];
                i++;
            }
            st.top++;
            st.data[st.top] = d;
            break;
        }
        ch = postexp[i];
        i++;
    }
    return st.data[st.top];
}

int main()
{
    int i = 0;
    char exp[] = {"(2*2)*1+3*2/1"};
    char postexp[MaxSize];
    trans(exp,postexp);
    while (postexp[i] != '\0')
    {
        printf("%c",postexp[i]);
        i++;
    }
    printf("\n");
    printf("运算结果为:%f.\n", Compvalue(postexp));
    system("pause");
    return 0;
}

后缀表达式求值如下:

while(从postexp中间读取字符ch,ch != '\0')
{
    若ch为数字,将后继的所有数字构成一个整数存放到数值栈st中
    若ch为 "+",则从数值栈st中退栈两个运算数,相加后进栈st中
    若ch为 "-",则从数值栈st中退栈两个运算数,相减后进栈st中
    若ch为 "*",则从数值栈st中退栈两个运算数,相乘后进栈st中
    若ch为 "/",则从数值栈st中退栈两个运算数,相除后进栈st中(若除数为0,则提示错误)
}
  • 运行结果

  • 参考资料:
    1 《新编数据结构习题与解析》

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!