再探利用C++的STL和堆棧編程思想實現數學四則運算計算結果

這次修改了上次的版本,利用了堆棧的編程思想,實現了支持括號的四則運算ios

跟上個版本同樣,吧表達式存儲到a.txt中:編程

結果保存在b.txt中:spa

 

堆棧編程思路:code

1. 創建兩個堆,一個字符堆,用於存儲+、-、*、/、%、=;一個數字堆,用於存儲數字對象

2. 建立兩個字符,一個存儲堆頂的操做符,一個存儲表達式中的操做符blog

3. 創建一個二維表,利用2.中的兩個操做符轉化爲行和列,在二維表中找到對應的判斷隊列

4. 如果小於,則表示,表達式中的操做符優先級比原先的操做符優先級高,直接壓入堆中存儲字符串

5. 如果大於,則表示堆頂的操做符優先級高,因此先計算,把數字堆中的兩個數彈出,計算結果,壓回堆中存儲,並把表達式中的操做符壓入字符堆中get

6. 若爲0,則表示表達式不合法string

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] << '\n';
 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 = '\0';
105     char ch = '\0';
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 }
相關文章
相關標籤/搜索