首页 > 代码库 > 新 四则运算
新 四则运算
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<time.h>#include<conio.h>#include<string>#include<vector>#include<stack>#include<map>#include<math.h>using namespace std;#define EPS 1e-5char s[50];int val[300];void gao(char str[])//把中缀表达式转换成后缀 { int cnt = 0; stack<int> st;//符号栈 int len = strlen(str); for(int i = 0;i<len;i++) { if(str[i]==‘(‘) st.push(str[i]);//对左括号的处理 else if(str[i]==‘)‘)//对右括号的处理 { while(!st.empty()) { int u = st.top(); st.pop(); if(u==‘(‘) break; s[cnt++] = u; } } else if(str[i]==‘+‘||str[i]==‘-‘||str[i]==‘*‘||str[i]==‘/‘)//对运算符的处理 { while(!st.empty()) { int u = st.top(); if(u==‘(‘||val[str[i]]>val[u]) break; st.pop(); s[cnt++] = u; } st.push(str[i]); } else//数字直接加入字符串 { s[cnt++] = str[i]; } } //把还在栈中的符号出栈 while(!st.empty()) { int u = st.top(); st.pop(); s[cnt++] = u; } s[cnt] = 0;}int gcd(int a,int b)//求最大公约数 { return b==0? a:gcd(b,a%b);}int lcm(int a,int b)//求最小公倍数 { return a*b/gcd(a,b);}pair<int,int> cal(char str[])//计算值,已分数表示 { int a,b; stack<pair<int,int> > st;//存放值的栈,用分数表示 int len = strlen(str); for(int i = 0;i<len;i++) { if(str[i]>=‘0‘&&str[i]<=‘9‘) { st.push(make_pair(str[i]-‘0‘,1));//现转化为分数 } else { pair<int,int> pa1 = st.top(); st.pop(); pair<int,int> pa2 = st.top(); st.pop(); int LCM = lcm(pa1.second,pa2.second); if(str[i]==‘+‘)//对加法的处理 { //if(pa1.second==0||pa2.second==0) return make_pair(0,0); int a = pa1.first*(LCM/pa1.second); int b = pa2.first*(LCM/pa2.second); pa1.first = a+b; pa1.second = LCM; st.push(pa1);//入栈 } else if(str[i]==‘-‘)//对减法的处理 { int a = pa1.first*(LCM/pa1.second); int b = pa2.first*(LCM/pa2.second); pa1.first = b-a; pa1.second = LCM; st.push(pa1); } else if(str[i]==‘*‘)//对乘法的处理 { pa1.first = pa1.first*pa2.first; pa1.second = pa1.second*pa2.second; st.push(pa1); } else//对除法的处理 { if(pa1.first==0) return make_pair(0,0);//改进了对除0的处理 int a = pa2.first*pa1.second; int b = pa2.second*pa1.first; pa1.first = a,pa1.second = b; st.push(pa1); } } } pair<int,int> pa = st.top(); st.pop(); int GCD = gcd(pa.first,pa.second); pa.first/=GCD,pa.second/=GCD;//化成最简形式 return pa; }int check(char str[])//判断str字符串是否合法 { int a = 0; int len = strlen(str); for(int i = 0;i<len;i++) { if(str[i]==‘(‘) a++; else if(str[i]==‘)‘)a--; if(a<0) return 0; if(str[i]==‘)‘&&i>=2&&str[i-2]==‘(‘) return 0; } if(str[0]==‘(‘&&str[strlen(str)-1]==‘)‘) return 0; return 1;}int ok(int a,int b,char str[]) //判断在str的ab位置放括号的合法性 { if(str[a]<‘0‘||str[b]<‘0‘||str[a]>‘9‘||str[b]>‘9‘) return 0; if(b<=a) return 0; if(a==0&&b==strlen(str)-1) return 0; if(a!=0&&str[a-1]==‘(‘&&str[b+1]==‘)‘) return 0; return 1;}void pro(char str[])//随机产生一个四则运算 { int sum = rand()%3; //随机括号的个数 for(int i = 0;i<=6;i++) { if(i%2==0) { str[i] = rand()%9+1+‘0‘; } else { int temp = rand()%4; if(temp==0) str[i] = ‘+‘; if(temp==1) str[i] = ‘-‘; if(temp==2) str[i] = ‘*‘; if(temp==3) str[i] = ‘/‘; } } str[7] = 0; for(int i= 1;i<=sum;i++)//循环增加括号 { int a = rand()%(7+2*i-2); int b = rand()%(7+2*i-2); while(!ok(a,b,str)) { a = rand()%(7+2*i-2); b = rand()%(7+2*i-2); } char ss[100]; int cnt = 0; for(int j = 0;j<7+2*i-2;j++) { if(j==a) { ss[cnt++] = ‘(‘; ss[cnt++] = str[j]; } else if(j==b) { ss[cnt++] = str[j]; ss[cnt++] = ‘)‘; } else ss[cnt++] = str[j]; } ss[cnt] = 0; int flag = check(ss); if(!flag) i--; else { strcpy(str,ss); } } // printf("%s\n",str); // gao(str); // pair<int,int> pa = cal(s); // printf("%d %d\n",pa.first,pa.second);}int is_ok(int a, int b)//判断a/b是否是无限循环小数 { if(b==0) return 0; if(a==0) return 1; map<int,int> ma; while(1) { while(a<b) a*=10; if(a%b==0) return 1; if(ma[a%b]) return 0; ma[a%b] = 1; a = a%b; } }void pri(int a,int b)//打印a/b的值 { if(a==0)//如果为0直接输出防止后面运算出bug { printf("0"); return; } printf("%d.",a/b); a = a%b; //a*=10; while(1) { int flag = 0; while(a<b) { a*=10; if(flag) printf("0"); flag++; } printf("%d",a/b); a = a%b; if(a==0) break; }}int is_num(char str[])//判断str是否为正整数 { int sum = 0; int len = strlen(str); for(int i = 0;i<len;i++) { if(str[i]>=‘0‘&&str[i]<=‘9‘) sum = sum*10+str[i]-‘0‘; else return -1; } if(sum==0) return -1; else return sum;}int main(int argc,char *argv[10]){ srand(time(0));//初始化随机种子 val[‘+‘] = val[‘-‘] = 1; val[‘*‘] = val[‘/‘] = 2;//运算符的优先级 if(argc==1)//功能1,2 { int sum = 0; char str[50]; for(int i = 1;i<=20;i++) { pro(str); gao(str); pair<int,int> pa = cal(s); // printf("%s\n",str); if(pa.second==0)//说明有除0现象 { i--; continue; } //printf("%d %d\n",abs(pa.first),abs(pa.second)); if(is_ok(abs(pa.first),abs(pa.second)))//不能整除继续寻找 { printf("%s\n?",str); } else { i--; continue; } //printf("%d %d\n",abs(pa.first),abs(pa.second)); //printf("%s\n",s); double res; scanf("%lf",&res); // printf("%lf\n",res-1.0*pa.first/pa.second); if(fabs(res-1.0*pa.first/pa.second)<EPS)//eps为误差值,用于double比较 { sum++; printf("答对了,你真是个天才!\n"); } else { if(abs(pa.first)%abs(pa.second)==0)//整除直接输出 { printf("在想想吧,答案似乎是%d喔!\n",pa.first/pa.second); } else { int flag = 0; if(pa.first<0) flag++; if(pa.second<0) flag++; printf("在想想吧,答案似乎是"); if(flag%2==1) printf("-"); pri(abs(pa.first),abs(pa.second)); printf("喔!\n"); } } } printf("你一共对了%d道题,共20道题.\n",sum); } if(argc==3)//功能3,4 { int flag = is_num(argv[2]); if(flag==-1) {printf("题目数量必须是 正整数。\n");return 0;} for(int i = 1;i<=flag;i++) { char str[100]; // printf("111111\n"); pro(str); gao(str); printf("%-50s%",str); // printf("%s\n",str); pair<int,int> pa = cal(s); // printf("%d 2222222\n",i); if(pa.second==0) { i--;continue; } if(pa.first%pa.second==0) printf("%d\n",pa.first/pa.second); else { int flag = 0; if(pa.first<0) flag++; if(pa.second<0) flag++; if(flag%2) printf("-"); pa.first = abs(pa.first);//正负提取,取绝对值 pa.second = abs(pa.second); if(pa.first/pa.second) printf("%d ",pa.first/pa.second); pa.first-=pa.first/pa.second*pa.second; printf("%d/%d\n",pa.first,pa.second);//输出答案 } // printf("11111\n"); } } return 0;}
结对作业:李峤 杜月
新 四则运算
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。