• 结对开发-1


    
    

    一、    设计思路:

    
    

    程序包含两部分,一部分是算式的生成,一部分是栈的使用用来判断和计算结果;

    
    

    算式生成,用的是调用子函数,因为每一个年级的出题要求不同所以对出题的范围加了条件限制;程序的结构框架大致为:

    
    

    程序开始将字符串数组宏定义,出题的数量和选择打印的方式都进行宏定义;

    
    

                For(         )

    
    

              {

    
    

                    For(      )

    
    

                    {

    
    

                        a> 产生左括号;(用switch…..case语句来判断;)

    
    

                         b> 产生数字:(其中,可以有分数小数和整数的产生)

    
    

                           其中不同年级选择的范围不同;

    
    

                        c>产生右括号;(右括号的产生是用左括号的数量来限制的)

    
    

                        d>产生运算符;运算符在输出最后一位数字之后就不会执行运算符产生的程序;)

    
    

    }

    
    

    }

    
    

    栈程序中:

    
    

    将算式生成的string类型的数组,转化为char类型的,读入到栈中,然后利用字符串优先级的判断,计算函数,我们的程序中不能出现负数所以在输出结果时加了结果判断;

      1 //组成员:禹慧慧 吕兰兰
      2 //四则运算,在前面的基础上实现判断正误  2016.3.19
      3 //我们的结果是如果选择dos界面,可以在界面上实现输入结果、判断正误与给出答案;如果选择txt,则打印出一份题目和一份答案
      4 //没有控制余数,都算成了小数
      5 #include<iostream>
      6 #include<ctime>
      7 #include<cmath>
      8 #include<sstream>
      9 #include<string>
     10 #include<fstream>
     11 #include<iomanip>
     12 #define MAX 1000
     13 using namespace std;
     14 
     15 int N;
     16 int way;
     17 string str[1000];
     18 ofstream outfile("questions.txt");
     19 ofstream outfile_1("answers.txt");
     20 
     21 
     22 class Input
     23 {
     24 public:
     25     Input()
     26     {
     27         for( int i = 0;i < MAX;i++ )
     28             Str_input[i] = '';
     29     }
     30     char Str_input[MAX];
     31     void inStr(string str11)
     32     {
     33         strcpy(Str_input,str11.c_str());
     34     }
     35 };
     36 
     37 /*输出模块*/
     38 class Output
     39 {
     40 public:
     41     Output()
     42     {
     43         result = 0;
     44     }
     45     void getRes( double res )
     46     {
     47         result = res;
     48     }
     49     void printRes(double &num_an)
     50     {
     51         num_an=result;
     52     }
     53 private:
     54     double result;
     55 };
     56 
     57 /*计算用的存储结构*/
     58 template <class Type>
     59 class STACK{                 
     60 private:
     61     Type base[MAX];
     62     int Size;
     63 public:
     64     STACK()
     65     {
     66         Size=0;
     67     };
     68     void push(Type a)     
     69     {
     70         base[Size]=a;
     71         Size++;
     72     }
     73     Type pop()           
     74     {
     75         return base[--Size];
     76     }
     77     int size()
     78     {return Size;}
     79 };
     80 
     81 
     82 /*计算的模块*/
     83 class jisuan
     84 {
     85 public: 
     86     bool shuhanshu(char);                 
     87     bool fuhanshu(char);                 
     88     int jckh(char);                  
     89     bool jcxsd(char *);              
     90     int pdyxj(char);                 
     91     double ToData(char*);             
     92     double Call(double,double,char);    
     93     int ppkh(char* buffer,int pos); 
     94     void Opr( STACK<char>&, STACK<double>&, int& ); 
     95     double Calculate(char*, double& );   
     96 
     97 };
     98 bool jisuan::shuhanshu(char ch)      
     99 {
    100     return ((ch>='0'&&ch<='9')||ch=='.')?true:false;
    101 }
    102 bool jisuan::fuhanshu(char ch)     
    103 {
    104     return (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='#')?true:false;
    105 }
    106 int jisuan::jckh(char ch)
    107 {
    108     if(ch=='(')
    109         return 1;
    110     if(ch==')')
    111         return -1;
    112     return 0;
    113 }
    114 bool jisuan::jcxsd(char *ch)
    115 {
    116     int a=0;
    117     for(int i=0;i<strlen(ch);i++)
    118         if(ch[i]=='.')          
    119             a++;
    120     if(a>1)
    121         return false;
    122     return true;
    123 }
    124 int jisuan::pdyxj(char ch)          //符号的优先极别
    125 {
    126     switch(ch)
    127     {
    128     case '+':
    129         return 0;
    130     case '-':
    131         return 0;
    132     case '*':
    133         return 1;
    134     case '/':
    135         return 1;
    136     case '#':
    137         return 0;
    138     default:
    139         return -1;
    140     }
    141 }
    142 double jisuan::ToData(char* ch)   //将数字转化为数值
    143 {
    144     int i,j,sumn=0;
    145     double sum=0.0;
    146     if(!jcxsd(ch)) return 0.0;
    147     for(i=0;i<strlen(ch);i++)           
    148     {
    149         if(ch[i]!='.')
    150             sumn=sumn*10+(ch[i]-'0');
    151         else break;
    152     }
    153     if(i<strlen(ch))
    154         for(j=i+1;j<strlen(ch);j++)        
    155             sum=sum*10+(ch[j]-'0');
    156     sum /= pow(10.0,(double)(strlen(ch)-1-i));
    157     return (sum+sumn);                    
    158 }
    159 double jisuan::Call(double sum,double data,char ch)
    160 {
    161     double ans=0.0;
    162     switch(ch)
    163     {
    164     case '+':
    165         ans=sum+data;
    166         break;
    167     case '-':
    168         ans=sum-data;
    169         break;
    170     case '*':
    171         ans=sum*data;
    172         break;
    173     case '/':
    174         if( data != 0.0 )
    175             ans=sum/data;
    176         else
    177         {
    178             cout<<"程序出现除0错误,终止!
    ";
    179             system("pause");
    180             exit(1);
    181         }
    182         break;
    183     case '#':
    184         return 0;
    185     default:ans=0.0;
    186         break;
    187     }
    188     return ans;
    189 }
    190 int jisuan::ppkh(char* buffer,int pos)     //利用栈找到匹配的括号
    191 {
    192     STACK<char> Temp;
    193     int i;
    194     for(i=pos;i<strlen(buffer);i++)
    195     {
    196         if(jckh(buffer[i])==1)
    197             Temp.push('0');
    198         if(jckh(buffer[i])==-1)
    199         {
    200             Temp.pop();
    201             if(Temp.size()==0) return i;
    202         }
    203     }
    204     return -1;
    205 }
    206 void jisuan::Opr(STACK<char>& symbol,STACK<double>& data,int& mark)
    207 {
    208     double sum;
    209     while(symbol.size()!=0)
    210     {
    211         char tem=symbol.pop();
    212         int temp=pdyxj(tem);
    213         symbol.push(tem);
    214         if(temp<mark)
    215             break;
    216         else{
    217             sum=Call(data.pop(),data.pop(),symbol.pop());
    218             data.push(sum);
    219         }
    220     }
    221 }
    222 double jisuan::Calculate(char* buffer,double& sum)   //字符串读入和各个函数调配
    223 {
    224     STACK<double> data;
    225     STACK<char> symbol;
    226     double ans;
    227     char temp[MAX];
    228     int ct=0,mark=0,tp=0;
    229     data.push(sum);
    230     while(ct<=strlen(buffer))
    231     {
    232         if(shuhanshu(buffer[ct]))            //如果是数字或小数点
    233         {
    234             while( ct < strlen(buffer) && shuhanshu(buffer[ct]) )
    235                 temp[tp++]=buffer[ct++];
    236             temp[tp]='';
    237             tp=0;                         //读到非数字也非小数为止
    238             ans=ToData(temp);             //把读到的字符串转化为数
    239             data.push(ans);
    240 
    241             if(ct==strlen(buffer))        //已经独到字符串末尾
    242             {
    243                 mark=0;
    244                 Opr(symbol,data,mark);    
    245                 sum=data.pop();           
    246                 return sum;               
    247             }
    248             else{
    249                 int mark=pdyxj(buffer[ct]);
    250                 Opr(symbol,data,mark);     //计算
    251             }
    252         }
    253         else if(fuhanshu(buffer[ct]))         //如果是运算符
    254             symbol.push(buffer[ct++]);     //运算符入symbol栈
    255         else
    256         {
    257             char BF[100];int k=0;          //如果都不是,则只能是括号
    258             while( jckh( buffer[ct] ) != 1 && ct <= strlen(buffer) )
    259                 BF[k++] = buffer[ct++];
    260             BF[k]='';
    261             if(jckh(buffer[ct])==1)       //一旦读到左括号,寻找它匹配的右括号
    262             {
    263                 int i,j;
    264                 char Temp[100];
    265                 for(i=ct+1,j=0;i<ppkh(buffer,ct);i++,j++)
    266                     Temp[j]=buffer[i];     //把这对括号中的字符串存入Temp
    267                 Temp[j]='';
    268                 data.push(Calculate(Temp,sum)); 
    269 
    270                 ct+=(strlen(Temp)+1);       
    271                 if(ct+1==strlen(buffer))   
    272                 {
    273                     mark=0;
    274                     Opr(symbol,data,mark);
    275                     sum=data.pop();
    276                     return sum;
    277                 }
    278                 else
    279                 {
    280                     mark=pdyxj(buffer[ct+1]); //不是的话继续计算
    281                     Opr(symbol,data,mark);
    282                 }
    283                 ct++;                           //读入下一个字符
    284             }
    285         }
    286     }
    287     return 0.;
    288 }
    289 int Expression(int grade,int N)
    290 {
    291 
    292     Input in;
    293     jisuan cl;
    294     Output out;
    295     double sum=0.0;
    296     double result;
    297     double answer;
    298     cout.precision(5);
    299     int random_a,random_b,random_c,random_e,random_f,random_g;
    300     int max,min;//整数
    301     int random_d;
    302     double random_h;
    303     
    304     //根据年级的不同选择每道题目的数的数量
    305     if(grade==2)
    306     {
    307         random_a=rand()%2+2;
    308         max=100;
    309         min=1;
    310     }
    311     if(grade==3)
    312     {
    313         random_a=rand()%3+2;
    314         max=500;
    315         min=1;
    316     }
    317     if(grade==4)
    318     {
    319         random_a=rand()%3+2;
    320         max=1000;
    321         min=1;
    322     }
    323     if(grade==5)
    324     {
    325         random_a=rand()%3+2;
    326         max=10000;
    327         min=1;
    328     }
    329     if(grade==6)
    330     {
    331         random_a=rand()%3+2;
    332         max=10000;
    333         min=1;
    334     }
    335     for(int j=0;j<N;j++)
    336     { 
    337         int flag=0;
    338         int count_p=0,count_q=0;//计算括号的数量
    339         for(int i=0;i<random_a;i++)
    340        {
    341           if(grade==2||grade==3||grade==4)
    342             {
    343                 random_b=0;//只有整数计算
    344             }
    345          if(grade==5||grade==6)
    346             {
    347                 random_b=rand()%3+0;
    348             }
    349         char str1[100];
    350         if(random_a>2&&i<(random_a-1))
    351         {
    352               random_d=rand()%4+0;
    353               switch(random_d)//控制括号的产生
    354               {
    355                 case 0:flag=0;break;
    356                 case 1:if(i!=(random_a-1)&&i<(random_a-2)){str[j]+='(';flag=1;count_q+=1;}break;
    357                 case 2:flag=0;break;
    358                 case 3:if(i!=(random_a-1)&&i<(random_a-2)){str[j]+='(';flag=1;count_q+=1;}break;
    359                 }
    360           }
    361             //数字的产生
    362             switch(random_b)
    363             {
    364                 
    365             case 0:
    366                 {
    367                     random_c=rand()%(max-min+1)+min;//整数
    368                     itoa(random_c,str1,10);
    369                     str[j]+=str1;
    370                    } break;
    371                    
    372             case 1:
    373                 {
    374                        random_h=(rand()%100)/100.0;//小数
    375                        random_e=rand()%10+0;
    376                        random_h+=random_e;
    377                        stringstream ss;
    378                        ss<<random_h;
    379                        str[j]+=ss.str();
    380                    }
    381                    break;
    382             case 2:
    383                  {//分数
    384                 do{
    385                     random_f=rand()%20+1;
    386                     random_g=rand()%10+1;
    387                    }while(random_g==random_f);
    388                 int number=1;
    389                 int m;
    390                 if(random_g>random_f)
    391                 {    
    392                      m=random_f;
    393                 }
    394                 else 
    395                 { m=random_g;}
    396                 for(int k=2;k<m+1;k++)
    397                 {
    398                      if((random_g%k==0)&&(random_f%k==0))
    399                     {
    400                          number=k;
    401                     } 
    402                 }
    403                 random_f=random_f/number;
    404                 random_g=random_g/number;
    405                 str[j]+='(';
    406                 if(random_g==1)
    407                 {
    408                      int n=0;
    409                      n=random_g;
    410                      random_g=random_f;
    411                      random_f=n;
    412                 }
    413                 itoa(random_f,str1,10);
    414                 str[j]+=str1;
    415                 str[j]+='/';
    416                 itoa(random_g,str1,10);
    417                 str[j]+=str1;
    418                 str[j]+=')';
    419                }break;
    420             }
    421             //右括号的产生
    422            if((flag!=1)&&(count_p!=count_q))
    423            {
    424                str[j]+=')';
    425                count_p+=1;
    426            }
    427            if(i==(random_a-1))
    428            {
    429                if(count_p<count_q)
    430                {
    431                    for(int k=0;k<(count_q-count_p);k++)
    432                    str[j]+=')';
    433                }
    434             }
    435         if(i!=(random_a-1))
    436         {
    437             random_b=rand()%4+0;
    438             switch(random_b)
    439             {
    440             case 0:{str[j]+='+';}break;
    441             case 1:{str[j]+='-';}break;
    442             case 2:{str[j]+='*';}break;
    443             case 3:{str[j]+='/';}break;
    444             }
    445         }
    446      }    
    447        
    448        in.inStr(str[j]);                              //输入模块
    449        out.getRes( cl.Calculate(in.Str_input,sum) ); //计算模块
    450        out.printRes(result);
    451        if (result<0)
    452        {
    453            str[j]="";
    454            j--;
    455            
    456        } 
    457        else
    458        {
    459            
    460            if(way==1)
    461            {
    462            cout<<str[j]<<"="<<endl;
    463            cout<<"请输入答案(6位有效数字):";
    464            cin>>answer;
    465          
    466            if (answer==result)
    467            {
    468 
    469                cout<<"回答正确!"<<endl;
    470            }
    471            else
    472            {
    473                cout<<"回答错误!"<<endl;
    474                cout<<"正确结果为:"<<result<<endl;
    475            }
    476            }
    477            else
    478            {
    479                outfile<<str[j]<<"=";
    480                outfile<<endl;
    481                outfile_1<<"正确结果为:"/*<<setprecision(5)*/<<result;
    482                outfile_1<<endl;
    483            }
    484        }
    485             
    486     }
    487     
    488     return 0;
    489 }    
    490 
    491 
    492     int main()
    493 {
    494     int grade;
    495     srand(time(0));
    496     
    497     cout<<"********************************************************************************"<<endl;
    498     cout<<"***************************欢迎使用小学四则运算出题系统*************************"<<endl;
    499     cout<<"********************************************************************************"<<endl;
    500     cout<<"*******作者:石家庄铁道大学   信1301-2     禹慧慧    吕兰兰    2016.3.19 *******"<<endl;
    501     cout<<"********************************************************************************"<<endl;
    502     cout<<"请选择打印方式:(0-TXT,1-DOS):";
    503     cin>>way;
    504     cout<<"********************************请选择年级**************************************"<<endl;
    505     cout<<"                                   2年级                                        "<<endl;
    506     cout<<"                                   3年级                                        "<<endl;
    507     cout<<"                                   4年级                                        "<<endl;
    508     cout<<"                                   5年级                                        "<<endl;
    509     cout<<"                                   6年级                                        "<<endl;
    510     cout<<"********************************************************************************"<<endl;
    511     cin>>grade;
    512         
    513     cout<<"请输入题目数量:";
    514     cin>>N;
    515     if(grade==2)
    516     {
    517     Expression(grade,N);
    518     }
    519     if(grade==3)
    520     {
    521         Expression(grade,N);
    522     }
    523     if(grade==4)
    524     {
    525         Expression(grade,N);
    526     }
    527     if(grade==5)
    528     {
    529         Expression(grade,N);
    530     }
    531     if(grade==6)
    532     {
    533         Expression(grade,N);
    534     }
    535     outfile.close();
    536     outfile_1.close();
    537  }
        
    三、    用时:计划花费20个小时,实际花费了23个小时;其中包括改错调试程序;
    四、    体会:本次试验又使用了新的知识;子函数的调用和栈的使用以及优先级的判断,这次实验花费的时间很长并且上网和查书找了很多东西。输入输出流的使用,以及栈的优先级的判            断,出栈入栈,计算结果,判断是否有错等。这次实验很有成就感!!!O(∩_∩)O~~
    五、程序运行截图:
    工作照:

    项目计划日志(单位:h):

    听课

    编写程序

    阅读相关书籍

    网上查找资料

    日总计

    周一

    2

    0

    1

    0

    3

    周二

    0

    3

    0.5

    3.5

    周三

    0

    3

    1

    0

    4

    周四

    2

    6

    1

    9

    周五

    0

    4

    1

    1

    6

    周六

    0

    3

    1

    4

    周日

    周总计

    4

    19

    3

          3.5

    29.5

    时间记录日志:(单位:min):

    日期

    开始时间

    结束时间

    中断时间

    净时间

    活动

    备注

    星期一

    14:00

    15:50

    10

    100

    听课

    软件工程

    20:00

    21:00

    0

    60

    看书

    构建之法

    星期二

    19:00

    19:30

    0

    30

    网上查找资料

    20:00

    23:00

    0

    180

    编程

    结对编程

    星期三

    15:00

    22:00

    180

    240

    编程和上网查找资料并且调试程序

    结对编程

    星期四

    14:00

    15:50

    10

    100

    听课

    软件工程

    16:00

    23:00

    60

    360

    编程

    结对编程

    星期五

    16:00

    21:00

    60

    240

    编程上网查找资料

    结对编程

    21:30

    22:30

    0

    60

    看书

    构建之法

    星期六

    19:00

    22:00

    0

    180

    编程和写博客

    结对编程

    缺陷记录日志:

    日期

    编号

    类型

    引入阶段

    排除阶段

    修复时间

    修复缺陷

    3/17

    1

    20

    编码

    调试

    20:00

    括号输出错误,运算不正确

    3/18

    2

    20

    编码

    调试

    19:00-21:00

    对栈的编写和运算结果

    3/19

    3

    20

    编码

    调试

    20:00-22:00

    括号的丢失和语法的错误。

     

    组员禹慧慧网址:http://www.cnblogs.com/yhhzxcvbnm/

  • 相关阅读:
    Attacklab markup
    Bomblab markup
    Diary & Solution Set 多校度假
    Solution 「CF 590E」Birthday
    MySQL 避坑宝典 来自小米的开源工具
    Hive SQL语法Explode 和 Lateral View
    「Ynoi2006」rsrams
    「Gym103069C」Random Shuffle
    「UOJ498」新年的追逐战
    「Nowhere」Helesta
  • 原文地址:https://www.cnblogs.com/lvlan/p/5296574.html
Copyright © 2020-2023  润新知