四则运算第二周

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 }

运行结果:

结对编程感想:

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

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

原文地址:https://www.cnblogs.com/qianhuihui/p/5874039.html