#include<stdio.h>
#include<math.h>
int treat(float a,float b,float c,float d);
float myF(int flag,float m,float n);//进行四则运算
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d);
int time,temp=0;
void main()
{
int i,j,k,t,again,res,flag;//res标志能否运算出24
float num[4];//存储所输入的4个整数
again=1;
while(again==1)
{
printf ("\n请输入4个数字(1~13):\n");
i=0;
flag=0;
while (flag==0)
{
i++;
for(i=0;i<4;i++)
{
scanf("%f",&num[i]);
if (num[i]<1 || num[i]>13 || num[i]!=int(num[i]))//判断是否为符合要求的整数
flag++;
}
if(flag!=0)
{
printf ("输入有误,请重新输入!\n",i);
flag=0;
}
else
flag=1;
}
for (i=0;i<4;i++)//4种排列4!=24,每种情况调用treat
for (j=0;j<4;j++)
if (j!=i)//第1个数和第2个数不能重复
for (k=0;k<4;k++)
if (k!=j && k!=i)//第3个数和第1、2个数不能重复
for (t=0;t<4;t++)
if (t!=i && t!=j && t!=k)//第1个数和第1、2、3个数不能重复
{
res=treat(num[i],num[j],num[k],num[t]);//调用函数进行加、减、乘、除运算
}
if (res==0)//不能运算出24
printf ("\n无解!\n");
else
printf ("\n1:继续!\n2:退出!\n");
scanf ("%d",&again);
}
}
int treat(float a,float b,float c,float d)//进行加减乘除运算
{
int i,j,k;
float sum1,sum2,sum3;//存储三次两两运算的结果
for (i=0;i<4;i++)//"+-*/"4个运算符号选三个,有4*4*4=64种
for (j=0;j<6;j++)//3种运算符排列,有3!=6种
for (k=0;k<6;k++)
{
if ((!(i==3 && b==0)) && (!(j==3 && c==0)) && (!(k==3 && d==0)))//括号的类型为(())
{//3为做除法运算的标志,除数为0时跳过==
sum1=myF(i,a,b);//a,b做以i为标志的运算,然后把值付给sum1
sum2=myF(j,sum1,c);//sum1,c做以j为标志的运算,然后把值付给sum2
sum3=myF(k,sum2,d);//sum2,d做以k为标志的运算,然后把值付给sum3
if (fabs(sum3-24)<0.1)//判断能否算出24,出现小数时,能够包含在内
{
temp++;//标志能运算出24
myPrint(1,i,j,k,a,b,c,d);//输出运算出24的表达式
}
}
if (k==2)//括号的类型为()*()
{
sum1=myF(i,a,b);//a,b做以i为标志的运算,然后把值付给sum1
sum2=myF(j,c,d);//c,d做以j为标志的运算,然后把值付给sum1
sum3=sum1*sum2;
if (fabs(sum3-24)<0.1)//出现小数时,能够包含在内
{
temp++;//标志能运算出24
myPrint(2,i,j,k,a,b,c,d);//输出运算出24的表达式
}
}
if (k==3)//括号的类型为()()
{
sum1=myF(i,a,b);//a,b做以i为标志的运算,然后把值付给sum1
sum2=myF(j,c,d);//c,d做以j为标志的运算,然后把值付给sum2
if (sum2!=0)
{
sum3=sum1/sum2;
if (fabs(sum3-24)<0.1)//出现小数时,能够包含在内
{
temp++;//标志能运算出24
myPrint(3,i,j,k,a,b,c,d);//输出运算出24的表达式
}
}
}
}
if (temp==0)
return 0;
else
return 1;
}
float myF(int flag,float m,float n)//进行四则运算
{
if (flag==0)
return (m+n);
if (flag==1)
return (m-n);
if (flag==2)
return (m*n);
if (flag==3)
if (n==0)
return 30000;//除数为0,则返回30000,不能运算出24
else
return (m/n);
if (flag==4)
return (n-m);
if (flag==5)
if (m==0)
return 30000;//除数为0,则返回30000,不能运算出24
else
return (n/m);
return 0;
}
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d)//利用参数type选择输出形式,利用参数i,j,k确定输出的运算符号
{
char sigle[6];//定义运算符号数组
sigle[0]='+';
sigle[1]='-';
sigle[2]='*';
sigle[3]='/';
sigle[4]='-';//减法不符合交换律
sigle[5]='/';//除法不符合交换律
if (type==1)//根据括号的类型做不同的输出
{
if(j==4 || j==5)//减法和除法
{
if (k==4 || k==5)//a*(b*(c+d))
printf("%2.0f %c (%2.0f %c (%2.0f %c %2.0f)) =24\n",d,sigle[k],c,sigle[j],a,sigle[i],b);
else//(a*(b+c))*
printf("(%2.0f %c (%2.0f %c %2.0f)) %c %2.0f =24\n",c,sigle[j],a,sigle[i],b,sigle[k],d);
}
else if (k==4 || k==5)//a*((b+c)*d)
{
printf("%2.0f %c ((%2.0f %c %2.0f) %c %2.0f) =24\n",d,sigle[k],a,sigle[i],b,sigle[j],c);
}
else//((a+b)*c)*d
printf("((%2.0f %c %2.0f) %c %2.0f) %c %2.0f =24\n",a,sigle[i],b,sigle[j],c,sigle[k],d);
}
if (type==2 || type==3)//(a+b)*(c+d)
{
printf("(%2.0f %c %2.0f) %c (%2.0f %c %2.0f) =24\n",a,sigle[i],b,sigle[k],c,sigle[j],d);
}
}
流程图:
首先,测试程序能不能运算出正确的结果,输入数据6,6,6,6,出现了44组符合要求的解,如图所示:
接着输入数据7,3,9,14,提示输入错误,重新输入4,8,2,13,能得到正确运行结果,如图所示:
输入1,1,1,2,不能运算得到24,显示“无解”,如图所示:
输入数据5,5,5,1,显示结果之后选择继续然后接着输入5,5,5,1 然后选择退出,运行结果如图所示:
心得体会
通过这次课程设计,让我对一个程序的数据结构有更全面更进一步的认识,根据不同的需求,采用不同的数据存储方式,不一定要用栈,二叉树等高级类型,有时用基本的一维数组,只要运用得当,也能达到相同的效果,甚至更佳,就如这次的课程设计题目----计算24点,通过用for的多重循环,结合if判断,舍弃多余的循环,提高了程序的运行效率。在编写这个程序的过程中,我复习了之前学的基本语法,更加深刻的认识到循环是大部分程序的基本要素。结合了上学期学的数据结构,改进算法,更加巩固了之前学的知识,比以前更能灵活运用。我觉得在输出方面,为提高运行效率,可以设计只输出一组解。还可以输入多个数,不局限在4个数。随着数量增加,循环增加,为提高运行效率,可以考虑更改数据类型。此次课程设计,我受益匪浅,巩固旧知识的同时,学习了新的知识。更重要的是,它使我编写程序更有信心了。