从中序表达式到逆序表达式(逆波兰式)(四则运算表达式求值)

将运算对象写在前面,而把运算符号写在后面。用这种表示法表示的表达式也称做后缀式。逆波兰式的特点在于运算对象顺序不变,运算符号位置反映运算顺序。采用逆波兰式可以很好的表示简单算术表达式,其优点在于易于计算机处理表达式。(逆波兰式不需要使用括号)
本份代码出自:http://wenku.baidu.com/view/23a5b73031126edb6f1a10aa.html
本份代码需要两个栈。一个是符号栈,一个是数字栈。
输入中序表达式如9+(3-1)*3+10/2#

这里写图片描述

这里写图片描述
计算过程
这里写图片描述

#include<stdio.h>
#include<math.h>
#define max 100
char ex[max];        /*存储后序表达式*/

/*函数功能:将中序表达式转化为后序表达式*/
void trans() {
    char str[max];   /*表达式字符串*/
    char stack[max]; /*运算符栈*/
    char ch;         /*当前字符*/
    int sum, i, j, t, top = 0; /*sum用来统计字符串的长度*/
                               /*t是数字栈栈顶指针*/
                               /*top是数字栈栈顶指针*/
    printf("*****************************************\n");
    printf("*输入一个求值的表达式,以#结束。*\n");
    printf("******************************************\n");
    printf("算数表达式:");

    i = 0;
    /*这个循环语句,获取一个用户输入的合法的表达式*/
    do {
        i++;
        scanf("%c", &str[i]);
    } while (str[i] != '#' && i != max);

    sum = i;
    t = 1;
    i = 1;
    ch = str[i];
    i++;
    //while循环,当前的字符不是#
    while (ch != '#') {
        //将该字符与运算符栈顶的运算符的优先关系相比较。
        //如果该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
        //括号的运算优先级高。
        switch (ch) {
        case '(':            /*判定为左括号,入符号栈*/
            top++;           /*栈顶指针+1*/
            stack[top] = ch;
            break;

        case ')': /*判定为右括号*/
            while (stack[top] != '(') {
                ex[t] = stack[top];/*把符号栈的栈顶元素压入另一个栈中*/
                top--;             /*符号栈的栈顶指针-1*/
                t++;               /*数字栈的栈顶指针+1*/
            }
            top--;
            break;
        case '+': /*判定为加减号*/
        case '-':
            while (top != 0 && stack[top] != '(') {
                ex[t] = stack[top];/*把符号栈的栈顶元素压入数字栈中*/
                top--;             /*符号栈的栈顶指针-1*/
                t++;               /*数字栈的栈顶指针+1*/
            }
            top++;
            stack[top] = ch;       /*不执行那个while循环的话,直接压入符号栈*/
            break;
        case '*': /*判定为乘除号*/
        case '/':
            while (stack[top] == '*' || stack[top] == '/') {
                ex[t] = stack[top];/*把符号栈的栈顶元素压入数字栈中*/
                top--;             /*符号栈的栈顶指针-1*/
                t++;               /*数字栈的栈顶指针+1*/
            }
            top++;
            stack[top] = ch;
            break;
        case ' ':/*滤去空格*/
            break;
        default:/*默认直接把数字压入数字栈*/
            while (ch >= '0' && ch <= '9') { /*判定为数字*/
                ex[t] = ch;                  /*把数字压入数字栈*/
                t++;                         /*数字栈栈顶指针+1*/
                /*这边的代码写得很巧妙*/
                ch = str[i];                 /*从字符串中取一个字符*/
                i++;                         /*字符数组下标+1*/
            }
            i--;
            ex[t] = '#';                     /*为每个数字加一个分隔符*/
            t++;
        }
        ch = str[i];
        i++;
    }
    /*把符号栈剩下的元素压进去*/
    while (top != 0) {
        ex[t] = stack[top];
        t++;
        top--;
    }
    ex[t] = '#';
    printf("\n原来的中序表达式:");
    for (j = 1; j < sum; j++)
        printf("%c", str[j]);
    printf("\n后缀表达式:");
    for (j = 1; j < t; j++)
        printf("%c", ex[j]);
}
void compvalue() { /*计算后缀表达式的值*/
    float stack[max], d; /*作为栈使用*/
    char ch;
    int t = 1, top = 0; /*t为ex下标,top为stack下标*/
    ch = ex[t];
    t++;
    //从左到右检查字符串
    while (ch != '#') {/*滤去#*/
        switch (ch) {
        //发现运算符,用栈顶的两个元素进行运算。
        case '+':
            stack[top - 1] = stack[top - 1] + stack[top];
            top--;
            break;
        case '-':
            stack[top - 1] = stack[top - 1] - stack[top];
            top--;
            break;
        case '*':
            stack[top - 1] = stack[top - 1] * stack[top];
            top--;
            break;

        case '/':
            if (stack[top] != 0)
                stack[top - 1] = stack[top - 1] / stack[top];
            else {
                printf("\n\t除零错误!\n");
                //exit(0);                   /*异常退出*/
            }
            top--;
            break;
        default:
            d = 0;
            while (ch >= '0' && ch <= '9') {
                d = 10 * d + ch - '0'; /*将数字字符转化为对应的数值*/
                ch = ex[t];
                t++;
            }
            top++;
            stack[top] = d;
        }
        ch = ex[t];
        t++;
    }
    printf("\n\t计算结果:%g\n", stack[top]);
}

int main() {
    trans();      //转化成逆波兰式
    compvalue();  //计算值
    return 0;
}

原文:http://blog.csdn.net/ilikeprograming/article/details/12358229

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页