zoukankan      html  css  js  c++  java
  • 四则运算第二周

    https://git.coding.net/qianhuihui/second-week.git
    ssh://git@git.coding.net:qianhuihui/second-week.git

    结对项目进一步更改如下:

      1 <br><br>#include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<time.h>
      5 #include<conio.h>
      6 #include<string>
      7 #include<vector>
      8 #include<stack>
      9 #include<map>
     10 #include<math.h>
     11 using namespace std;
     12 #define EPS 1e-5
     13 char s[50];
     14 int val[300];
     15 void gao(char str[])//把中缀表达式转换成后缀
     16 {
     17      int cnt  = 0;
     18      stack<int> st;//符号栈
     19      int len = strlen(str);
     20      for(int i = 0;i<len;i++)
     21      {
     22         if(str[i]=='(') st.push(str[i]);//对左括号的处理
     23         else if(str[i]==')')//对右括号的处理
     24         {
     25               while(!st.empty())
     26               {
     27                    int u = st.top();
     28                    st.pop();
     29                    if(u=='(') break;
     30                    s[cnt++] = u;
     31               }
     32         }
     33         else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')//对运算符的处理
     34         {
     35             while(!st.empty())
     36             {
     37                 int u = st.top();
     38                 if(u=='('||val[str[i]]>val[u]) break;
     39                 st.pop();
     40                 s[cnt++] = u;
     41             }
     42             st.push(str[i]);
     43         }
     44         else//数字直接加入字符串
     45         {
     46             s[cnt++] = str[i];
     47         }
     48          
     49      }   
     50      //把还在栈中的符号出栈
     51      while(!st.empty())
     52      {
     53         int u = st.top();
     54         st.pop();
     55         s[cnt++]  = u;
     56      }
     57      s[cnt] = 0;
     58 }
     59 int gcd(int a,int b)//求最大公约数
     60 {
     61     return b==0? a:gcd(b,a%b);
     62 }
     63 int lcm(int a,int b)//求最小公倍数
     64 {
     65     return a*b/gcd(a,b);
     66 }
     67 pair<int,int> cal(char str[])//计算值,已分数表示
     68 {
     69      
     70     int a,b;
     71     stack<pair<int,int> > st;//存放值的栈,用分数表示
     72     int len = strlen(str);
     73     for(int i = 0;i<len;i++)
     74     {
     75         if(str[i]>='0'&&str[i]<='9')
     76         {
     77             st.push(make_pair(str[i]-'0',1));//现转化为分数
     78         }
     79         else
     80         {
     81             pair<int,int> pa1 = st.top();
     82             st.pop();
     83             pair<int,int> pa2 = st.top();
     84             st.pop();
     85             int LCM = lcm(pa1.second,pa2.second);
     86             if(str[i]=='+')//对加法的处理
     87             {
     88                 //if(pa1.second==0||pa2.second==0) return make_pair(0,0);
     89                 int a = pa1.first*(LCM/pa1.second);
     90                 int b = pa2.first*(LCM/pa2.second);
     91                 pa1.first = a+b;
     92                 pa1.second = LCM;
     93                 st.push(pa1);//入栈
     94             }
     95             else if(str[i]=='-')//对减法的处理
     96             {
     97                 int a = pa1.first*(LCM/pa1.second);
     98                 int b = pa2.first*(LCM/pa2.second);
     99                 pa1.first = b-a;
    100                 pa1.second = LCM;
    101                 st.push(pa1);
    102             }
    103             else if(str[i]=='*')//对乘法的处理
    104             {
    105                 pa1.first = pa1.first*pa2.first;
    106                 pa1.second = pa1.second*pa2.second;
    107                 st.push(pa1);
    108                  
    109             }
    110             else//对除法的处理
    111             {
    112                 if(pa1.first==0) return make_pair(0,0);//改进了对除0的处理
    113                 int a = pa2.first*pa1.second;
    114                 int b = pa2.second*pa1.first;
    115                 pa1.first = a,pa1.second = b;
    116                 st.push(pa1);
    117             }
    118         }
    119     }
    120     pair<int,int> pa = st.top();
    121     st.pop();
    122     int GCD = gcd(pa.first,pa.second);
    123     pa.first/=GCD,pa.second/=GCD;//化成最简形式
    124     return pa;
    125      
    126 }
    127 int check(char str[])//判断str字符串是否合法
    128 {
    129     int a = 0;
    130     int len = strlen(str);
    131     for(int i = 0;i<len;i++)
    132     {
    133         if(str[i]=='(') a++;
    134         else if(str[i]==')')a--;
    135         if(a<0) return 0;   
    136         if(str[i]==')'&&i>=2&&str[i-2]=='(') return 0;
    137     }
    138     if(str[0]=='('&&str[strlen(str)-1]==')') return 0;
    139     return 1;
    140 }
    141  
    142 int ok(int a,int b,char str[])  //判断在str的ab位置放括号的合法性
    143 {
    144    if(str[a]<'0'||str[b]<'0'||str[a]>'9'||str[b]>'9') return 0;
    145    if(b<=a) return 0;
    146    if(a==0&&b==strlen(str)-1) return 0;
    147    if(a!=0&&str[a-1]=='('&&str[b+1]==')') return 0;
    148    return 1;
    149 }
    150  
    151 void pro(char str[])//随机产生一个四则运算
    152 {
    153     int sum = rand()%3; //随机括号的个数
    154     for(int i = 0;i<=6;i++)
    155     {
    156         if(i%2==0)
    157         {
    158             str[i] = rand()%9+1+'0';
    159         }
    160         else
    161         {
    162             int temp = rand()%4;
    163             if(temp==0) str[i] = '+';
    164             if(temp==1) str[i] = '-';
    165             if(temp==2) str[i] = '*';
    166             if(temp==3) str[i] = '/';
    167         }
    168     }
    169     str[7] = 0;
    170     for(int i= 1;i<=sum;i++)//循环增加括号
    171     {
    172         int a = rand()%(7+2*i-2);
    173         int b = rand()%(7+2*i-2);
    174         while(!ok(a,b,str))
    175         {
    176             a  = rand()%(7+2*i-2);
    177             b  = rand()%(7+2*i-2);
    178         }
    179         char ss[100];
    180         int cnt = 0;
    181         for(int j = 0;j<7+2*i-2;j++)
    182         {
    183             if(j==a)
    184             {
    185                 ss[cnt++] = '(';
    186                 ss[cnt++] = str[j];
    187             }
    188             else if(j==b)
    189             {
    190                 ss[cnt++]  = str[j];
    191                 ss[cnt++] = ')';
    192             }
    193             else ss[cnt++] = str[j];
    194         }
    195         ss[cnt] = 0;
    196         int flag = check(ss);
    197         if(!flag) i--;
    198         else
    199         {
    200             strcpy(str,ss);
    201         }
    202     }
    203   //  printf("%s
    ",str);
    204   //  gao(str);
    205    // pair<int,int> pa = cal(s);
    206    // printf("%d %d
    ",pa.first,pa.second);
    207 }
    208 int is_ok(int a, int b)//判断a/b是否是无限循环小数
    209 {
    210     if(b==0) return 0;
    211     if(a==0) return 1;
    212     map<int,int> ma;
    213     while(1)
    214     {
    215         while(a<b) a*=10;
    216         if(a%b==0) return 1;
    217         if(ma[a%b]) return 0;
    218         ma[a%b] = 1;
    219         a = a%b;
    220     }
    221      
    222 }
    223 void pri(int a,int b)//打印a/b的值
    224 {
    225     if(a==0)//如果为0直接输出防止后面运算出bug
    226     {
    227         printf("0");
    228         return;
    229     }
    230     printf("%d.",a/b);
    231     a = a%b;
    232     //a*=10;
    233     while(1)
    234     {
    235         int flag = 0;
    236         while(a<b)
    237         {
    238             a*=10;
    239             if(flag)
    240             printf("0");
    241             flag++;
    242         }
    243         printf("%d",a/b);
    244         a = a%b;
    245         if(a==0) break;
    246     }
    247 }
    248 int is_num(char str[])//判断str是否为正整数
    249 {
    250     int sum = 0;
    251     int len = strlen(str);
    252     for(int i = 0;i<len;i++)
    253     {
    254         if(str[i]>='0'&&str[i]<='9') sum = sum*10+str[i]-'0';
    255         else return -1;
    256     }
    257     if(sum==0) return -1;
    258     else return sum;
    259 }
    260 int main(int argc,char *argv[10])
    261 {
    262     srand(time(0));//初始化随机种子
    263     val['+'] = val['-'] = 1;
    264     val['*'] = val['/'] = 2;//运算符的优先级
    265     if(argc==1)//功能1,2
    266     {
    267         int sum  = 0;
    268         char str[50];
    269         for(int i = 1;i<=20;i++)
    270         {
    271             pro(str);
    272             gao(str);
    273          
    274             pair<int,int> pa = cal(s);
    275         //  printf("%s
    ",str);
    276             if(pa.second==0)//说明有除0现象
    277             {
    278                 i--;
    279                 continue;
    280             }
    281             //printf("%d %d
    ",abs(pa.first),abs(pa.second));
    282             if(is_ok(abs(pa.first),abs(pa.second)))//不能整除继续寻找
    283             {
    284                 printf("%s
    ?",str);
    285             }
    286             else
    287             {
    288                 i--;
    289                 continue;
    290             }
    291             //printf("%d %d
    ",abs(pa.first),abs(pa.second));
    292             //printf("%s
    ",s);
    293             double res;
    294             scanf("%lf",&res);
    295         //  printf("%lf
    ",res-1.0*pa.first/pa.second);
    296             if(fabs(res-1.0*pa.first/pa.second)<EPS)//eps为误差值,用于double比较
    297             {
    298                 sum++;
    299                 printf("答对了,你真是个天才!
    ");
    300             }
    301             else
    302             {
    303                 if(abs(pa.first)%abs(pa.second)==0)//整除直接输出
    304                 {
    305                    printf("在想想吧,答案似乎是%d喔!
    ",pa.first/pa.second);
    306                 }
    307                 else
    308                 {
    309                     int flag = 0;
    310                     if(pa.first<0) flag++;
    311                     if(pa.second<0) flag++;
    312                      
    313                     printf("在想想吧,答案似乎是");
    314                     if(flag%2==1) printf("-");
    315                     pri(abs(pa.first),abs(pa.second));
    316                     printf("喔!
    ");
    317                      
    318                 }
    319             }
    320              
    321         }
    322         printf("你一共对了%d道题,共20道题.
    ",sum);
    323     }
    324     if(argc==3)//功能3,4
    325     {
    326         int flag  = is_num(argv[2]);
    327         if(flag==-1) {printf("题目数量必须是 正整数。
    ");return 0;}
    328         for(int i = 1;i<=flag;i++)
    329         {
    330             char str[100];
    331         //  printf("111111
    ");
    332             pro(str);
    333          
    334             gao(str);
    335             printf("%-50s%",str);
    336         //  printf("%s
    ",str);
    337             pair<int,int> pa = cal(s);
    338             //  printf("%d 2222222
    ",i);
    339              
    340             if(pa.second==0) {
    341                 i--;continue;
    342             }
    343             if(pa.first%pa.second==0) printf("%d
    ",pa.first/pa.second);
    344             else
    345             {
    346                     int flag = 0;
    347                     if(pa.first<0) flag++;
    348                     if(pa.second<0) flag++;
    349                     if(flag%2) printf("-");
    350                     pa.first = abs(pa.first);//正负提取,取绝对值
    351                     pa.second = abs(pa.second);
    352                     if(pa.first/pa.second) printf("%d ",pa.first/pa.second);
    353                     pa.first-=pa.first/pa.second*pa.second;
    354                     printf("%d/%d
    ",pa.first,pa.second);//输出答案
    355                      
    356             }
    357         //  printf("11111
    ");
    358         }
    359          
    360     }
    361     return 0;
    362 }

    运行结果:

    结对编程感想:

      结对编程进行过程中确实会遇到意见不统一的问题,但是讨论过后最终一定能得到一个确定的结果,再这样的编程过程中,自己的想法会有所改变,也可以学习到结对成员编程的优秀之处,感觉在接下来的合作中,两个人的编程效率会有所提高。

      按要求另附结对工作照片,有室友帮助拍摄。

  • 相关阅读:
    numpy中linspace用法 (等差数列创建函数)
    Ubuntu环境下 matplotlib 图例中文乱码
    转载: 广义逆矩阵
    matplotlib.pyplot中add_subplot方法参数111的含义
    转载:(论文) 二次指数平滑法中确定初始值的简便方法
    图像处理之 opencv 学习---opencv 中的常用算法
    图像处理之 opencv 学习---矩阵的操作
    编译异常之static和extern---more than one storage class specified
    格式转换至yuv422转 yuv420
    阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_6 自定义类型转换器代码编写
  • 原文地址:https://www.cnblogs.com/qianhuihui/p/5874039.html
Copyright © 2011-2022 走看看