zoukankan      html  css  js  c++  java
  • 再探利用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 }
  • 相关阅读:
    swift 初见-4运算符与字符串操作
    IOS中数据持久化1-CoreData
    swift 初见-3
    swift 初见-2
    系统硬件1-短信,打电话
    swift 初见-1
    socket理解流程图
    文件操作方法fscanf
    Prim模板
    树剖求LCA模板
  • 原文地址:https://www.cnblogs.com/SamRichard/p/3645155.html
Copyright © 2011-2022 走看看