xingma0910

学习中……

导航

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

表达式求值

前缀式:就是将操作符放到数值的前面;如: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] = '\0';
 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!\n");
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 }

 

posted on 2014-08-22 09:48  xingma0910  阅读(1467)  评论(0编辑  收藏  举报