zoukankan      html  css  js  c++  java
  • 四则运算3+psp0

    题目要求:

      1.程序可以判断用户的输入答案是否正确,如果错误,给出正确答案,如果正确,给出提示。

      2.程序可以处理四种运算的混合算式。

      3.要求两人合作分析,合作编程,单独撰写博客。

    团队成员:张绍佳、杜文星(博客:http://www.cnblogs.com/duwenxing/p/5294508.html

    设计思路:

          代码分写于不同的文件中;

          ① head.h:在头文件head.h中,将其他.cpp文件中所需要的头文件、全局变量的声明、函数的声明都写在此文件中。

          ② fraction.cpp:此文件中主要定义了一些与分数有关的函数,如分数的生成化简、加减乘除、分数的输出、分数转字符串等。

          ③ stack.cpp:此文件的主要功能是将所给的运算式的结果计算出来,主要思路是利用栈先将运算式转化为后缀式,然后再利用栈将后缀式的结果求出,重难点是转化后缀式时如何将真分数当做一个整体,我们的解决方法是通过识别 “(” 和 “)” 来识别;同时在计算时即使是整数我们也将其转化为分数处理,故调用了fraction中的一些方法来进行加减乘除。

         ④yunsuan.cpp:这个文件的主要功能是实现运算式的生成,并判断使用者输入的结果和题目的答案是否相同来判断对错,并输出正确数与错误数。

         ⑤main.cpp:主函数所在的头文件,主要功能是和用户进行交互。

    工作照:

    代码:

    head.h

     1 #pragma once
     2 #include<iostream>
     3 #include<ctime>
     4 #include<strstream>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<string>
     8 #include<cstdio>
     9 #include<cmath>
    10 #define random(l,h) (rand()%(h-l+1)+l)//宏定义
    11 #define maxsize 1000
    12 using namespace std;
    13 extern int flag;
    14 /*stack.cpp*/
    15 struct Fraction
    16 {
    17     int up, down;
    18     string high, low;
    19 };
    20 void trans(string exp, char postexp[]);
    21 Fraction compvalue(char postexp[]);//计算后缀表达式的值
    22 /*fraction.cpp*/
    23 int gcd(int a, int b);//求a,b的最大公约数
    24 int max(int a, int b);
    25 int min(int a, int b);
    26 Fraction fraction(int up, int down);//生成分数
    27 Fraction fra(int d, int u);//生成真分数;
    28 Fraction reduction(Fraction result);//分数的化简
    29 Fraction add(Fraction f1, Fraction f2);//分数的加法
    30 Fraction minus1(Fraction f1, Fraction f2);//分数的减法
    31 Fraction multi(Fraction f1, Fraction f2);//分数的乘法
    32 Fraction divide(Fraction f1, Fraction f2);//分数的除法
    33 void ShowResult(Fraction f);//输出分数
    34 string FraToString(Fraction f);//将分数转换为string类型
    35 /*yunsuan.cpp*/
    36 int suiji(int down, int up);//随机生成1至n的整数
    37 bool is_unique(string str, vector <string> s);//判断生成的运算式是否重复
    38 void yunsuan(int time, int low, int high, int fl1, int fl2, int fl3);

    fraction.cpp

      1 #include"head.h"
      2 int gcd(int a, int b)//求a,b的最大公约数
      3 {
      4     if (b == 0) return a;
      5     else return gcd(b, a%b);
      6 }
      7 
      8 int max(int a, int b)//返回两个整数中较大的整数
      9 {
     10     int h = a >= b ? a : b;
     11     return h;
     12 }
     13 int min(int a, int b)//返回两个整数中较小的整数
     14 {
     15     int l = a <= b ? a : b;
     16     return l;
     17 }
     18 Fraction fraction(int up, int down)//生成分数
     19 {
     20     Fraction result;
     21     result.up = up;
     22     result.down = down;
     23     strstream ss, kk;
     24     ss << result.up; ss >> result.high;
     25     kk << result.down; kk >> result.low;
     26     return result;
     27 }
     28 Fraction fra(int d,int u)//生成真分数
     29 {
     30     Fraction result;
     31     int temp1 = suiji(d, u);//调用function函数随机生成两个随机整数
     32     int temp2 = suiji(d, u);
     33     result.up = min(temp1, temp2);
     34     result.down = max(temp1, temp2);
     35     strstream s1, s2;
     36     s1 << result.up; s1 >> result.high;
     37     s2 << result.down; s2 >> result.low;
     38     return result;
     39 }
     40 Fraction reduction(Fraction result)//分数的化简
     41 {
     42     if (result.down < 0)
     43     {
     44         result.up = -result.up;
     45         result.down = -result.down;
     46     }
     47     if (result.up == 0)
     48     {
     49         result.down = 1;
     50     }
     51     else
     52     {
     53         int d = gcd(abs(result.up), abs(result.down));
     54         result.up /= d;
     55         result.down /= d;
     56     }
     57     strstream s3, s4;
     58     s3 << result.up; s3 >> result.high;
     59     s4 << result.down; s4 >> result.low;
     60     return result;
     61 }
     62 Fraction add(Fraction f1, Fraction f2)//分数的加法
     63 {
     64     Fraction result;
     65     result.up = f1.up*f2.down + f1.down * f2.up;
     66     result.down = f1.down*f2.down;
     67     return reduction(result);
     68 }
     69 Fraction minus1(Fraction f1, Fraction f2)//分数的减法
     70 {
     71     Fraction result;
     72     result.up = f1.up*f2.down - f1.down*f2.up;
     73     result.down = f1.down*f2.down;
     74     return reduction(result);
     75 }
     76 Fraction multi(Fraction f1, Fraction f2)//分数的乘法
     77 {
     78     Fraction result;
     79     result.up = f1.up*f2.up;
     80     result.down = f1.down*f2.down;
     81     return reduction(result);
     82 }
     83 Fraction divide(Fraction f1, Fraction f2)//分数的除法
     84 {
     85     Fraction result;
     86     result.up = f1.up*f2.down;
     87     result.down = f1.down*f2.up;
     88     return reduction(result);
     89 }
     90 void ShowResult(Fraction f)//输出分数
     91 {
     92     f = reduction(f);
     93     if (f.down == 1) cout << f.up;
     94     else cout << f.up << "\" << f.down;
     95 }
     96 string FraToString(Fraction f)//将分数转换为string类型
     97 {
     98     string result;
     99     if (f.down == 1) result = f.high;
    100     else result = f.high + "\" + f.low;
    101     return result;
    102 }

    stack.cpp

      1 #include"head.h"
      2 struct
      3 {
      4     char data[maxsize];//存放运算符
      5     int top;//栈顶指针
      6 }op;//定义运算符栈
      7 void trans(string exp, char postexp[])//exp[]为算数表达式,postexp[]为后缀表达式
      8 {
      9     char ch;
     10     int i = 0, j = 0;//i作为exp的下标,j作为postexp的小标
     11     op.top = -1;
     12     ch = exp[i];
     13     i++;
     14     while (ch != '')//exp表达式未扫描完时循环
     15     {
     16         switch (ch)
     17         {
     18         case'['://判定为左括号
     19         {
     20             op.top++;
     21             op.data[op.top] = ch;
     22         }break;
     23         case']'://判定为右括号,此时将’[‘之前的运算符依次出栈并存放到postexp中
     24         {
     25             while (op.data[op.top] != '[')
     26             {
     27                 postexp[j] = op.data[op.top];
     28                 j++;
     29                 op.top--;
     30             }
     31             op.top--;//将’[‘删除
     32         }break;
     33         case'+'://为’+‘或’-‘时,其优先级不大于栈顶的任何运算符,直到’]‘为止
     34         case'-':
     35         {
     36             while (op.top != -1 && op.data[op.top] != '[')
     37             {
     38                 postexp[j] = op.data[op.top];
     39                 j++;
     40                 op.top--;
     41             }
     42             op.top++;
     43             op.data[op.top] = ch;
     44         }break;
     45         case'*'://为’*‘或’/’时,其优先级不大于栈顶为‘*’或‘/‘的优先级,直到’['
     46         case'/':
     47         {
     48             while (op.top != -1 && op.data[op.top] != '[' && (op.data[op.top] == '*' || op.data[op.top] == '/'))
     49             {
     50                 postexp[j] = op.data[op.top];
     51                 j++;
     52                 op.top--;
     53             }
     54             op.top++;
     55             op.data[op.top] = ch;
     56         }break;
     57         case' ':break;//过滤掉空格
     58         case'('://将分数当成一个整体放到postexp中
     59         {
     60             while (ch != ')')
     61             {
     62                 postexp[j]=ch;
     63                 j++;
     64                 ch = exp[i];
     65                 i++;
     66             }
     67             postexp[j]=ch; j++;//将')'放到postexp中
     68         }break;
     69         default:
     70         {
     71             while (ch >= '0'&&ch <= '9')//判定为数字
     72             {
     73                 postexp[j] = ch;
     74                 j++;
     75                 ch = exp[i];
     76                 i++;
     77             }
     78             i--;
     79             postexp[j] = '#';//用#标示一个数值的结束
     80             j++;
     81         }
     82         }
     83         ch = exp[i];
     84         i++;
     85     }
     86     while (op.top != -1)//此时exp扫描完毕,栈不空时出栈并存放到postexp中
     87     {
     88         postexp[j] = op.data[op.top];
     89         j++;
     90         op.top--;
     91     }
     92     postexp[j] = '';//给postexp表达式添加结束标识
     93 }
     94 struct
     95 {
     96     Fraction data[maxsize];//存放数值
     97     int top;//栈顶指针
     98 }st;
     99  Fraction compvalue(char postexp[])//计算后缀表达式的值
    100 {
    101     double d;
    102     char ch;
    103     int i = 0;//postexp的下标
    104     st.top = -1;
    105     ch = postexp[i];
    106     i++;
    107     while (ch != '')//postexp字符串未扫描完事完成循环
    108     {
    109         switch (ch)
    110         {
    111         case'+':
    112         {
    113             st.data[st.top - 1] = add(st.data[st.top - 1], st.data[st.top]);
    114             st.top--;
    115         }break;
    116         case'-':
    117         {
    118             st.data[st.top - 1] = minus1(st.data[st.top - 1], st.data[st.top]);
    119             st.top--;
    120         }break;
    121         case'*':
    122         {
    123             st.data[st.top - 1] = multi(st.data[st.top - 1], st.data[st.top]);
    124             st.top--;
    125         }break;
    126         case'/':
    127         {
    128             st.data[st.top - 1] = divide(st.data[st.top - 1], st.data[st.top]);
    129             st.top--;
    130         }break;
    131         case'(':
    132         {
    133             double high = 0, low = 0;
    134             ch = postexp[i]; i++;//删除‘(‘
    135             while (ch != '\')
    136             {
    137                 high = 10 * high + ch - '0';
    138                 ch = postexp[i];
    139                 i++;
    140             }
    141             ch = postexp[i]; i++;//删除’’
    142             while (ch != ')')
    143             {
    144                 low = 10 * low + ch - '0';
    145                 ch = postexp[i];
    146                 i++;
    147             }
    148             st.top++;
    149             Fraction re = fraction(high, low);
    150             st.data[st.top] = re;
    151         }break;
    152         default:
    153         {
    154             d = 0;
    155             while (ch >= '0'&&ch <= '9')//将数字字符转化为对应的数值存放到d中
    156             {
    157                 d = 10 * d + ch - '0';
    158                 ch = postexp[i];
    159                 i++;
    160             }
    161             st.top++;
    162             Fraction re = fraction(d, 1);
    163             st.data[st.top] = re;
    164         }
    165         }
    166         ch = postexp[i];
    167         i++;
    168     }
    169     return st.data[st.top];
    170 }

    yunsuan.cpp

      1 #include"head.h"
      2 int flag = 1;
      3 int suiji(int down, int up)//随机生成1至n的整数
      4 {
      5     int low = down, high = up;
      6     if (flag)
      7     {
      8         flag = 0;
      9         srand((unsigned)time(NULL));//种子
     10     }
     11     int result = random(down, up);
     12     return result;
     13 
     14 }
     15 bool is_unique(string str, vector <string> s)//判断生成的运算式是否重复
     16 {
     17     int count = 0;
     18     for (int i = 0; i < s.size(); i++)
     19     {
     20         if (str!=s[i])
     21         {
     22             count++;
     23         }
     24         else break;
     25     }
     26     bool flag0 = count == s.size() ? true : false;
     27     return flag0;
     28 }
     29 void yunsuan(int time, int low, int high, int fl1, int fl2, int fl3)//根据参数要求生成四则运算式
     30 {
     31     int integer1, integer2;
     32     int ch1, ch2, ch3, ch4;//switch语句的选项
     33     char sign;//运算符号
     34     int times = time;//题目数
     35     vector <string> str;//str用来保存生成的题目
     36     int right = 0, wrong = 0;
     37     for (int i = 1; i <= times;)
     38     {
     39         int flag4 = 1;//flag4用来标记运算式是否是刚开始生成
     40         string first, second, cal;//四则运算的第一个运算数和第二个运算数
     41         int number = suiji(1, 9);//number为参与运算的参数个数
     42         for (int j = 1; j <= number;)
     43         {
     44             //-------------------------------------------------------------------------------------
     45             if (fl1 == 1)//允许乘除发参与运算的情况
     46             {
     47                 ch1 = suiji(1, 4);//随机生成运算符号
     48                 switch (ch1)
     49                 {
     50                 case 1:sign = '+'; break;
     51                 case 2:sign = '-'; break;
     52                 case 3:sign = '*'; break;
     53                 case 4:sign = '/'; break;
     54                 default:cout << "有错误!" << endl; break;
     55                 }
     56             }
     57             else//不允许乘除法参与运算的情况
     58             {
     59                 ch1 = suiji(1, 2);//随机生成运算符号
     60                 switch (ch1)
     61                 {
     62                 case 1:sign = '+'; break;
     63                 case 2:sign = '-'; break;
     64                 default:cout << "有错误!" << endl; break;
     65                 }
     66             }
     67             //-------------------------------------------------------------------------------------
     68             if (fl3 == 1)//允许真分数参与运算
     69             {
     70                 ch2 = suiji(1, 3);//四则运算题目的三种情况
     71                 switch (ch2)
     72                 {
     73                 case 1://整数和整数
     74                 {
     75                     strstream si, so;
     76                     integer1 = suiji(low, high);
     77                     si << integer1; si >> first;
     78                     integer2 = suiji(low, high);
     79                     so << integer2; so >> second;
     80                 }break;
     81                 case 2://整数和真分数
     82                 {
     83                     strstream ss;
     84                     integer1 = suiji(low, high);
     85                     ss << integer1; ss >> first;
     86                     Fraction f = reduction(fra(low, high));
     87                     second = "(" + f.high + "\" + f.low + ")";
     88                 }break;
     89                 case 3://真分数和真分数
     90                 {
     91                     Fraction f1 = reduction(fra(low, high));
     92                     Fraction f2 = reduction(fra(low, high));
     93                     first = "(" + f1.high + "\" + f1.low + ")";
     94                     second = "(" + f2.high + "\" + f2.low + ")";
     95                 }break;
     96                 default:cout << "有错误!" << endl; break;
     97                 }
     98             }
     99             else//不允许真分数参与运算
    100             {
    101                 strstream si, so;
    102                 integer1 = suiji(low, high);
    103                 si << integer1; si >> first;
    104                 integer2 = suiji(low, high);
    105                 so << integer2; so >> second;
    106             }
    107             //-------------------------------------------------------------------------------------
    108             if (fl2 == 1)//允许括号(【】)参与运算
    109             {
    110                 ch4 = suiji(1, 4);
    111                 switch (ch4)
    112                 {
    113                 case 1:
    114                 {
    115                     if (flag4 == 1)//flag4为1表示运算式还未生成前两个运算数
    116                     {
    117                         cal = first + sign + second;
    118                         flag4 = 0;
    119                     }
    120                     else
    121                     {
    122                         cal = cal + sign + first;//将以生成的运算式个新生成的运算数连接起来
    123                     }
    124                 }break;
    125                 case 2:
    126                 {
    127                     if (flag4 == 1)
    128                     {
    129                         cal = second + sign + first;
    130                         flag4 = 0;
    131                     }
    132                     else
    133                     {
    134                         cal = second + sign + cal;
    135                     }
    136                 }break;
    137                 case 3:
    138                 {
    139                     if (flag4 == 1)
    140                     {
    141                         cal = "[" + first + sign + second + "]";//添加括号【】的情况
    142                         flag4 = 0;
    143                     }
    144                     else
    145                     {
    146                         cal = "[" + cal + sign + first + "]";
    147                     }
    148                 }break;
    149                 case 4:
    150                 {
    151                     if (flag4 == 1)
    152                     {
    153                         cal = "[" + second + sign + first + "]";
    154                         flag4 = 0;
    155                     }
    156                     else
    157                     {
    158                         cal = "[" + second + sign + cal + "]";
    159                     }
    160                 }break;
    161                 default:cout << "有错误!" << endl; break;
    162                 }
    163             }
    164             else//不允许括号(【】)参与运算
    165             {
    166                 ch4 = suiji(1, 2);//输出的两种情况
    167                 switch (ch4)
    168                 {
    169                 case 1:
    170                 {
    171                     if (flag4 == 1)
    172                     {
    173                         cal = first + sign + second;
    174                         flag4 = 0;
    175                     }
    176                     else
    177                     {
    178                         cal = cal + sign + first;
    179                     }
    180                 }break;
    181                 case 2:
    182                 {
    183                     if (flag4 == 1)
    184                     {
    185                         cal = second + sign + first;
    186                         flag4 = 0;
    187                     }
    188                     else
    189                     {
    190                         cal = second + sign + cal;
    191                     }
    192                 }break;
    193                 default:cout << "有错误!" << endl; break;
    194                 }
    195             }
    196             j++;
    197         }
    198         //------------------------------------------------------------------------------
    199         if (str.empty())//若sr为空,则将第一个生成的运算式添加到vector中
    200         {
    201             str.push_back(cal);
    202             cout << "(" << i << ")." << cal << "=";
    203 
    204             string answer;
    205             cin >> answer;
    206             char postexp[maxsize];
    207             trans(cal, postexp);
    208             Fraction re = compvalue(postexp);
    209             string result = FraToString(re);
    210             if (answer == result)
    211             {
    212                 cout << "正确!" << endl;
    213                 right++;
    214             }
    215             else
    216             {
    217                 cout << "错误!,正确答案为:" << result << endl;
    218                 wrong++;
    219             }
    220             i++;
    221         }
    222         if (is_unique(cal, str))//判断生成的运算式和之前已经生成的运算式是否重复
    223         {
    224             str.push_back(cal);//将生成的运算式添加到str中
    225             cout << "(" << i << ")." << cal << "=";
    226             string answer;
    227             cin >> answer;
    228             char postexp[maxsize];
    229             trans(cal, postexp);
    230             Fraction re = compvalue(postexp);
    231             string result = FraToString(re);
    232             if (answer == result)
    233             {
    234                 cout << "正确!" << endl;
    235                 right++;
    236 
    237             }
    238             else
    239             {
    240                 cout << "错误!,正确答案为:" << result << endl;
    241                 wrong++;
    242             }
    243             i++;
    244         }
    245         else {}
    246     }
    247     cout << "**********************************************************************************" << endl;
    248     cout << "你做对了" << right << "道题,做错了" << wrong << "道题" << endl;
    249 }

    main.cpp

     1 #include"head.h"
     2 int main()
     3 {
     4     cout << "请输入题目数(1~100):";
     5     int times, down, up, flag1, flag2, flag3, flag4;
     6     cin >> times;//times至题目数
     7     cout << "请输入数值绝对值范围:";
     8     cin >> down >> up;//[down,up]为运算数范围
     9     cout << "是否允许乘除发参与运算(y/n):";
    10     char yn1;
    11     cin >> yn1;
    12     yn1 == 'y' || yn1 == 'Y' ? flag1 = 1 : flag1 = 0;
    13     cout << "是否允许括号([])参与运算(y/n):";
    14     char yn2;
    15     cin >> yn2;
    16     yn2 == 'y' || yn2 == 'Y' ? flag2 = 1 : flag2 = 0;//flag2判断是否允许括号参与运算
    17     cout << "是否允许真分数参与运算(y/n):";
    18     char yn3;
    19     cin >> yn3;
    20     yn3 == 'y' || yn3 == 'Y' ? flag3 = 1 : flag3 = 0;//flag3判断是否允许真分数参与运算
    21     cout << "**********************************************************************************" << endl;
    22     yunsuan(times, down, up, flag1, flag2, flag3);
    23     system("pause");
    24     return 0;
    25 }

    截图:

    项目计划总结:

    日期任务 听课/时 编写程序/时 查阅资料/时 日总计/时
    星期一 2 2   4
    星期二   2   2
    星期三   3 1 4
    星期四 2 3   5
    星期五   4   4
    星期六   5  2 7
    星期日        
    周总计 4 19 3

    26

     时间记录日志:

    日期 开始时间 结束时间 中断时间 净时间/分 活动 备注
    3/14 14:00 15:50 10 100 听课 软件工程上课
      19:00 21:00   60 编写程序 作业
      21:00 21:30   30 阅读书籍 《构建之法》
    3/15 19:00 21:00  20 90 查资料,编写程序 作业
    3/16  15:00  16:30  15  90 编写程序  作业
       17:00  18:00    60  查阅资料和阅读构建之法  
       21:00  22::00   60   编写程序  作业
    3/17 14:00 15:50  10 100 听课 软件工程上课
      18:30 22:10   50 查资料,编写程序 作业
    3/18 16:20 18:30  10 120 编程  
      19:10 21:45   145 查阅资料+编程  
    3/19 9:00 11:40   160 编程 作业
       12:20  15:00    160  调试程序  
       15:00        写博客  

    缺陷日志:

    日期 编号 缺陷内容 引入阶段 排除阶段 修复时间 修复缺陷
    3月14日 1

    如何计算运算

    编写代码 思考、查资料 80+ 利用栈来实现
    3月18日 2

    如何识别真分

    编写代码 思考、查资料 120+ 利用“(” 和 “)”来识别
  • 相关阅读:
    登录功能实现
    JavaScript中的apply()方法和call()方法使用介绍
    导致JSON无法解析的问题
    git
    Xcode 与 macOS 系统版本的兼容问题
    创建多个Target
    验证合法身份证
    Xcode 6创建预编译头文件.pch
    About In-App Purchase
    Xcode 6制作通用framework库
  • 原文地址:https://www.cnblogs.com/me-tts/p/5294977.html
Copyright © 2011-2022 走看看