再探利用C++的STL和堆栈编程思想实现数学四则运算计算结果

此次修改了上次的版本,利用了堆栈的编程思想,实现了支持括号的四则运算

跟上个版本一样,吧表达式存储到a.txt中:

结果保存在b.txt中:

堆栈编程思路:

1. 建立两个堆,一个字符堆,用于存储+、-、*、/、%、=;一个数字堆,用于存储数字

2. 创建两个字符,一个存储堆顶的操作符,一个存储表达式中的操作符

3. 建立一个二维表,利用2.中的两个操作符转化为行和列,在二维表中找到对应的判断

4. 若是小于,则表示,表达式中的操作符优先级比原先的操作符优先级高,直接压入堆中存储

5. 若是大于,则表示堆顶的操作符优先级高,所以先计算,把数字堆中的两个数弹出,计算结果,压回堆中存储,并把表达式中的操作符压入字符堆中

6. 若为0,则表示表达式不合法

7. 若为=,则有两种情况,一个是表达式计算完成,把结果存储到answer中。另外一种是括号配对了,需要把前括号pop了

以上是主思路,次思路跟上次一样:

1. 打开a.txt;

2. 利用getline吧每行的表达式读出来,存入string类对象中;

3. 循环读取,循环计算结果;

4. 循环完成,把answer中的结果存储到b.txt;

差不多就这样,下面附上代码:

  1 // Arithmetic3.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <iostream>
  6 #include <fstream>
  7 #include <string>
  8 #include <vector>
  9 #include <deque>
 10 #include <stack>
 11 #include <stdio.h>
 12 
 13 using namespace std;
 14 
 15                 //+   -   *   /   %   (   )   =
 16 char ss[8][8] ={{'>','>','<','<','<','<','>','>'},
 17                 {'>','>','<','<','<','<','>','>'},
 18                 {'>','>','>','>','>','<','>','>'},
 19                 {'>','>','>','>','>','<','>','>'},
 20                 {'>','>','>','>','>','<','>','>'},
 21                 {'<','<','<','<','<','<','=','0'},
 22                 {'>','>','>','>','>','0','>','>'},
 23                 {'<','<','<','<','<','<','0','='}};
 24 //大于号,弹出数字,进行计算,小于号,压入堆栈中
 25 
 26 //把字符转化成相应的行和列
 27 void getRowCol (const char stackCh, const char ch, int& row, int& col)
 28 {
 29     switch (stackCh)
 30     {
 31     case '+':
 32         row = 0;
 33         break;
 34     case '-':
 35         row = 1;
 36         break;
 37     case '*':
 38         row = 2;
 39         break;
 40     case '/':
 41         row = 3;
 42         break;
 43     case '%':
 44         row = 4;
 45         break;
 46     case '(':
 47         row = 5;
 48         break;
 49     case ')':
 50         row = 6;
 51         break;
 52     case '=':
 53         row = 7;
 54         break;
 55     }
 56     switch (ch)
 57     {
 58     case '+':
 59         col = 0;
 60         break;
 61     case '-':
 62         col = 1;
 63         break;
 64     case '*':
 65         col = 2;
 66         break;
 67     case '/':
 68         col = 3;
 69         break;
 70     case '%':
 71         col = 4;
 72         break;
 73     case '(':
 74         col = 5;
 75         break;
 76     case ')':
 77         col = 6;
 78         break;
 79     case '=':
 80         col = 7;
 81         break;
 82     }
 83 
 84 }
 85 
 86 //写入文件
 87 void writeAnswer(vector<int>& iAnswer)
 88 {
 89     ofstream ofs("b.txt");
 90     for(vector<int>::size_type ix = 0; ix != iAnswer.size(); ix++)
 91     {
 92         ofs << iAnswer[ix] << '
';
 93     }
 94     ofs.close();
 95 }
 96 
 97 
 98 void countAnswer(vector<int>& iAnswer, string& str)
 99 {
100     int temp = 0;
101     int row = 0 ,col = 0;
102     stack<int> iStk;            //定义数据堆
103     stack<char> cStk;            //定义字符堆
104     char stackCh = '';
105     char ch = '';
106     cStk.push('=');             //先把=压入字符堆中,以备匹配等号
107     for (string::size_type ix = 0; ix != str.size(); ix++)
108     {
109         //如果是数字,先判断下一个字符是否也是数字,如果不是,就压入数据堆中
110         if (str[ix] >= '0' && str[ix] <= '9')
111         {
112             temp = str[ix] - '0' + temp * 10;
113             if (str[ix + 1] < '0' || str[ix + 1] > '9')
114             {
115                 iStk.push(temp);
116             }
117         }
118         else
119         {
120 /*            iStk.push(temp);*/
121             temp = 0;
122             stackCh = cStk.top();       //弹出字符堆的堆顶字符
123             ch = str[ix];                //读取字符串中的字符
124             if (ch == '=' || ch == ')') //遇到 = 号,或者),先执行判断
125             {
126                 ix--;
127             }
128             getRowCol(stackCh,ch,row,col); ////把字符转化成相应的行和列
129             switch(ss[row][col])
130             {
131             case '=':  //遇到括号匹配,或者=号匹配,计算结束
132                 if ( ch == '=')
133                 {
134                     iAnswer.push_back(iStk.top());
135                     return ;
136                 }
137                 else
138                 {
139                     cStk.pop();
140                     ix++;
141                 }
142 
143                 break;
144             case '>':  //取出堆中的两个数据,执行计算
145                 {
146                     int num2 = iStk.top();
147                     iStk.pop();
148                     int num1 = iStk.top();
149                     iStk.pop();
150                     stackCh = cStk.top();
151                     cStk.pop();
152                     if (ch != '=' && ch != ')')
153                     {
154                         cStk.push(ch);
155                     }
156                     switch(stackCh)
157                     {
158                     case '+':
159                         num1 += num2;
160                         break;
161                     case '-':
162                         num1 -= num2;
163                         break;
164                     case '*':
165                         num1 *= num2;
166                         break;
167                     case '/':
168                         num1 /= num2;
169                         break;
170                     case '%':
171                         num1 %= num2;
172                         break;
173                     }
174                     iStk.push(num1);
175                     break;
176                 }
177             case '<': //压入堆中
178                 cStk.push(ch);
179                 break;
180             case '0': //表达式错误
181                 cout << "error arithmetic" << endl;
182                 return ;
183             }
184         }
185     }
186 }
187 
188 
189 void countMath()
190 {
191     ifstream ifs("a.txt");
192     if (!ifs.is_open())
193     {
194         ifs.clear();
195         fstream fs("a.txt",ios_base::out); //如果打开失败就创建文件a.txt
196         fs.close();
197         ifs.open("a.txt");
198     }
199     string temp;
200     deque<string> sDeq;
201     while (!ifs.eof())
202     {
203         getline(ifs,temp);                //按行读取数据,存储到双端队列中
204         sDeq.push_back(temp);
205     }
206 
207     ifs.close();
208 
209     vector<int> iAnswer;
210     for (deque<string>::size_type ix = 0; ix != sDeq.size(); ix++)
211     {
212         string str;
213         str = sDeq.front();
214         sDeq.pop_front();
215         ix--;
216         //计算每一行的表达式
217         countAnswer(iAnswer,str);
218     }
219 
220     writeAnswer(iAnswer);
221 }
222 
223 int _tmain(int argc, _TCHAR* argv[])
224 {
225     countMath();
226     return 0;
227 }
原文地址:https://www.cnblogs.com/SamRichard/p/3645155.html