c语言数据结构实现后缀表达式求值

一般人在书写的时候习惯是书写中缀表达式也叫逆波兰式,然而在计算机处理的时候中缀表达式的效率远小于后缀表达式,即操做数在前面,运算符在后面例如:算法

中缀表达式 A+B     后缀表达式AB+express

                 A+B*C                     ABC*+数组

               A*B+C*D                AB*CD*+函数

             D+A/(B_C)              DABC-/+spa

后缀表达式计算时,全部运算按照运算符出现的顺序,严格从左到右,每一个操做符取前两个操做数进行运算,运算后的结果仍然做为下次的操做数,这样作与中缀表达式彻底等价,即计算次序和运算结果彻底相同,而且再也不使用括号,逆波兰式的主要特色在于运算对象(操做数)不变,运算符号反应运算顺序,采用逆波兰式很好的表达简单运算符,其优势在于已与计算机处理表达式,所以算术表达式计算问题进行分解,先将中缀转换为后缀表达式在进行计算。code

这个过程一共分为两步,第一步,把输入的表达式转换为后缀表达式,第二步,计算后缀表达式对象


转化后缀表达式的过程:字符串

1.当读到操做数后存入数组中,input

2.当读到运算符的时候,把优先级比这个运算符小或者等于的全部运算符出栈,再把这个运算符入栈string

3.当读左括号的时候,入栈

4.当读到右括号得时候,将靠近栈顶的左括号以前的全部运算符出栈,存入数组中而后再将左括号出栈


计算后缀表达式的过程:

对于计算后缀表达式而言,只是按照天然地从左到右的逻辑顺序,当遇到操做数的时候就入栈,当遇到运算符的时候,就取栈顶的前两个元素进行操做,而后操做完的数,再入栈,而后继续扫描,一直直到表达式遍历完,

实现算法以下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <string>
#include <stack>
#include<algorithm>
#define MAXN 1000
using namespace std;
stack<char> s;  //定义了一个栈

char *tranfExp(char* exp)
{
    char tempStr[1000];//保存后缀表达式的字符串

    int i=0,j=0;
    while(exp[i] !='\0')
    {
        if(exp[i]>='0' &&exp[i]<='9')  //若是是数字字符串就保存到后缀表达式字符串中
        {
            tempStr[j++] = exp[i];
        }
        else if(exp[i] == '(' )  //若是是左括号及入栈
        {
            s.push(exp[i]);
        }
        else if(exp[i] == ')' )  //若是是右括号就把接近栈顶的左括号上面全部的运算符出栈存进字符串中  左括号出栈
        {
            while(s.empty() == false)
            {
                if(s.top() == '(' )
                {
                    s.pop();
                    break;
                }
                else
                {
                   tempStr[j++] = s.top();
                   s.pop();
                }
            }
        }
        else if(exp[i] == '+' || exp[i] == '-')   //若是的事+-|操做符就把比他优先级高或者等于的全部运算符出栈进入字符串
        {
            while(s.empty() == false)
            {
                char ch = s.top();
                if(ch == '+'||ch == '-'||ch == '/'||ch == '*')
                {

                   tempStr[j++] = s.top();
                   s.pop();
                }
                else
                    break;
            }
            s.push(exp[i]);
        }
        else if(exp[i] == '*' || exp[i] == '/')  //相似于扫描到+- 只是若是栈中有=-运算符就不用出栈  由于运算符优先级比较小
        {
            while(s.empty() == false)
            {
                char ch = s.top();
                if(ch == '/' || ch=='*')
                {
                    tempStr[j++] = s.top();
                   s.pop();
                }
                else
                    break;
            }
            s.push(exp[i]);
        }
        i++;
    }
    while(s.empty() == false)   //把栈中剩余的全部运算符出栈
    {
        tempStr[j++] = s.top();
        s.pop();
    }
    tempStr[j] = 0;   //最后一个赋值为0  也就是字符串结束的标志
    return tempStr;   //返回已经获得的后缀表达式
}
int calcExp(char* exp)// 计算后缀表达式
{
    puts(exp);   //展现已经获得的后缀
    while( !s.empty() )
      s.pop();
    int i=0;
    while(exp[i] != '\0')
    {
        if(exp[i]>='0' && exp[i]<='9')
        {
            s.push(exp[i]-'0');
        }
        else if(exp[i] == '-')
        {
            int m = s.top();
            s.pop();
            int n = s.top();
            s.pop();
            s.push(n-m);
        }
        else if(exp[i] == '+')
        {
            int m = s.top();
            s.pop();
            int n = s.top();
            s.pop();
            s.push(n+m);
        }
        else if(exp[i] == '/')
        {
            int m = s.top();
            s.pop();
            int n = s.top();
            s.pop();
            s.push(n/m);
        }
        else if(exp[i] == '*')
        {
            int m = s.top();
            s.pop();
            int n = s.top();
            s.pop();
            s.push(n*m);
        }
        i++;
    }
  /* while(s.empty() == false)
    {
         printf("%d",s.top());
         s.pop();
    }*/
    printf("\n\n\n");
    return s.top();
}
int main()
{
   char str[1000];
   char* tranStr;
   tranStr = (char *)malloc(100*sizeof(char));
   printf("please input expression with kuohao:\n");
   scanf("%s",str);
   tranStr =  tranfExp(str);//中缀表达式转换为后缀表达式函数
   //puts(tranStr); //输出转换后的后缀表达式
   printf("%d",calcExp(tranStr));
   return 0;
}