• 表达式求值(只包括小括号)


    表达式求值

    前缀式:就是将操作符放到数值的前面;如:a+b :  +ab;

    中缀式:就是将操作符放在数值中间,其实就是我们平时生活中所写的正常的表达式。如:a+b;

    后缀式:就是将操作符放在数值的后面,比如:a+b:——ab+.

    对于表达式求值,最简单的当然是对后缀表达式(也称为逆波兰式)进行求值了。

    而我们生活中所写的运算表达式,一般都是中缀表达式。但是我们计算的时候用到的却是后缀表达式。这就需要我们首先将中缀表达式转换为后缀表达式,然后再进行运算了。

    1、中缀式转换为后缀式

    下面是将中缀式(常见运算式)转换为后缀式的算法(该算法只能处理只包含“(”和“)”的运算符):

    栈底放‘#’,从左至右逐字读取中缀式:
       a.当当前字符为数字时,直接输出;
    b.当当前字符为"("时,将其压栈;
    c.当当前字符为")"时,则弹出堆栈中最上的"("之前的所有运算符并输出,然后删除堆栈中的"(" ;
    d.当当前字符为运算符时,则依次弹出堆栈中优先级大于等于当前运算符的(到"("之前为止),输出,再将当前运算符压栈;
    e.当为"#"时,弹出所有栈中的内容输出

    中缀式:a*(b+c)/d+e

    后缀式:abc+*d/e+

    2、后缀式计算

    计算后缀表达式的具体算法如下:

    首先定义一个栈stk,用于存放计算结果。

      a.当前元素为数值,直接入栈;

      b.如果当前元素是运算符,则将stk中栈顶的两个元素弹出:m,n;

      c.根据运算符类别(+、-、*、/)计算t = n op m;(m 是第一个弹出栈的元素);

      d.将计算的结果t重新压入栈stk中。

      e.当后缀表达式还未结束,转到a继续执行,否则计算结束。stk此时的栈顶元素即是最后的计算结果。

    具体的实现代码如下所示:

      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <stack>
      5 #include <vector>
      6 #include <map>
      7 #include <string>
      8 #include <algorithm>
      9 using namespace std;
     10 
     11 map<char,int> priority;
     12 
     13 void setPriority()
     14 {
     15     priority['-'] = 1;
     16     priority['+'] = 1;
     17     priority['*'] = 2;
     18     priority['/'] = 2;
     19 }
     20 
     21 void InfixToPostfix(const string &src,vector<char> &exp)
     22 {
     23     int i,n;
     24     stack<char> op;
     25 
     26     n = src.size();
     27     for (i = 0; i < n; i++)
     28     {
     29         switch(src[i])
     30         {
     31         case '(':
     32             op.push(src[i]);
     33             break;
     34         case ')':
     35             while (op.size() != 0 && op.top() != '(')
     36             {
     37                 exp.push_back(op.top());
     38                 op.pop();
     39             }
     40             op.pop();
     41             break;
     42         case '+':
     43         case '-':
     44         case '*':
     45         case '/':
     46             while (op.size() != 0 && priority[op.top()] >= priority[src[i]])
     47             {
     48                 exp.push_back(op.top());
     49                 op.pop();
     50             }
     51             
     52             op.push(src[i]);
     53             break;
     54         case ' ':
     55             break;
     56         default:
     57             while (isdigit(src[i]) && i<n)
     58             {
     59                 exp.push_back(src[i]);
     60                 i++;
     61             }
     62             i--;
     63             exp.push_back('#');
     64         }
     65     }
     66     while (op.size() !=0 )
     67     {
     68         exp.push_back(op.top());
     69         op.pop();
     70     }
     71 }
     72 
     73 void displayExp(vector<char> &src)
     74 {
     75     int i,n;
     76     n = src.size();
     77     for (i = 0; i < n; i++)
     78     {
     79         cout<<src[i];
     80     }
     81     cout<<endl;
     82 }
     83 
     84 void initArray(char a[],int n)
     85 {
     86     int i;
     87     for (i = 0; i < n; i++)
     88     {
     89         a[i] = '';
     90     }
     91 }
     92 
     93 int calculate(int a,int b,char op)
     94 {
     95     switch (op)
     96     {
     97     case '+':
     98         return a+b;
     99         break;
    100     case '-':
    101         return a-b;
    102         break;
    103     case '*':
    104         return a*b;
    105         break;
    106     case '/':
    107         if (b != 0)
    108         {
    109             return a/b;
    110         }
    111         else
    112         {
    113             return 0;
    114         }
    115     default:
    116         perror("error!
    ");
    117     }
    118 }
    119 
    120 int calculatePostfix(const vector<char> &src)
    121 {
    122     stack<int> stk;
    123     char str[10];
    124     int i,n,temp,k;
    125     int opd1,opd2;
    126     int result;
    127 
    128     n = src.size();
    129     
    130     for (i = 0; i < n; i++)
    131     {
    132         switch(src[i])
    133         {
    134         case '#':
    135             break;
    136         case '+':
    137         case '-':
    138         case '*':
    139         case '/':
    140             opd2 = stk.top();
    141             stk.pop();
    142             opd1 = stk.top();
    143             stk.pop();
    144             result = calculate(opd1,opd2,src[i]);
    145             stk.push(result);
    146             break;
    147         default:
    148             k = 0;
    149             while ((isdigit(src[i])) && (i < n))
    150             {
    151                 str[k++] = src[i++];
    152             }
    153             temp = atoi(str);
    154             stk.push(temp);
    155             initArray(str,10);
    156             i--;
    157         }
    158     }
    159     return result;
    160 }
    161 
    162 int main()
    163 {
    164     ifstream in("data.txt");
    165     string src;
    166     int result;
    167     vector<char> postfix;
    168     getline(in,src);
    169     
    170     setPriority();
    171     InfixToPostfix(src,postfix);
    172     displayExp(postfix);
    173     result = calculatePostfix(postfix);
    174     cout<<src<<" = "<<result;
    175     cout<<endl;
    176     return 0;
    177 }
  • 相关阅读:
    ListView 操作
    Delphi 浏览器WebBrowser
    XE6 c++builder Edit垂直居中
    HTML 表格标签
    HTML 标签说明
    Ubuntu下如何解压缩zip,tar,tar.gz,tar.bz2文件
    Ubuntu 12.04下mysql的安装与配置
    Ubuntu12.04下apache服务器的安装也配置
    Ubuntu12.04下tomcat的安装与配置
    Ubuntu 12.04下jdk的安装与配置
  • 原文地址:https://www.cnblogs.com/xingma0910/p/3928622.html
Copyright © 2020-2023  润新知