這次修改了上次的版本,利用了堆棧的編程思想,實現了支持括號的四則運算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 }