首页 > 代码库 > 新 四则运算

新 四则运算

#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;}

  技术分享技术分享技术分享

 

 

结对作业:李峤  杜月

新 四则运算