四则运算第二周
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算第二周相关的知识,希望对你有一定的参考价值。
https://git.coding.net/qianhuihui/second-week.git
ssh://[email protected]: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\n",str); 204 // gao(str); 205 // pair<int,int> pa = cal(s); 206 // printf("%d %d\n",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\n",str); 276 if(pa.second==0)//说明有除0现象 277 { 278 i--; 279 continue; 280 } 281 //printf("%d %d\n",abs(pa.first),abs(pa.second)); 282 if(is_ok(abs(pa.first),abs(pa.second)))//不能整除继续寻找 283 { 284 printf("%s\n?",str); 285 } 286 else 287 { 288 i--; 289 continue; 290 } 291 //printf("%d %d\n",abs(pa.first),abs(pa.second)); 292 //printf("%s\n",s); 293 double res; 294 scanf("%lf",&res); 295 // printf("%lf\n",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("答对了,你真是个天才!\n"); 300 } 301 else 302 { 303 if(abs(pa.first)%abs(pa.second)==0)//整除直接输出 304 { 305 printf("在想想吧,答案似乎是%d喔!\n",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("喔!\n"); 317 318 } 319 } 320 321 } 322 printf("你一共对了%d道题,共20道题.\n",sum); 323 } 324 if(argc==3)//功能3,4 325 { 326 int flag = is_num(argv[2]); 327 if(flag==-1) {printf("题目数量必须是 正整数。\n");return 0;} 328 for(int i = 1;i<=flag;i++) 329 { 330 char str[100]; 331 // printf("111111\n"); 332 pro(str); 333 334 gao(str); 335 printf("%-50s%",str); 336 // printf("%s\n",str); 337 pair<int,int> pa = cal(s); 338 // printf("%d 2222222\n",i); 339 340 if(pa.second==0) { 341 i--;continue; 342 } 343 if(pa.first%pa.second==0) printf("%d\n",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\n",pa.first,pa.second);//输出答案 355 356 } 357 // printf("11111\n"); 358 } 359 360 } 361 return 0; 362 }
运行结果:
结对编程感想:
结对编程进行过程中确实会遇到意见不统一的问题,但是讨论过后最终一定能得到一个确定的结果,再这样的编程过程中,自己的想法会有所改变,也可以学习到结对成员编程的优秀之处,感觉在接下来的合作中,两个人的编程效率会有所提高。
按要求另附结对工作照片,有室友帮助拍摄。
以上是关于四则运算第二周的主要内容,如果未能解决你的问题,请参考以下文章