一、简介
本程序的思想和算法来自于C语言教材后的实训项目,程序通过用户输入四个整数计算出能够通过加减乘除得到数字24的所有表达式,程序的设计有别于一般通过穷举实现的方式,效率得到提高。算法介绍如下:
如用户输入1,2,3,4四个数字,先将其看成四个集合即{1},{2},{3},{4},整个叫做第一集群,后通过任意两个集合加减乘除{1,2},{1,3},{1,4},{2,3},{2,4},{3,4}六个集合叫做第二集群,而第三集群由第一集群和第二集群产生,而第四集群可由第一集群和第三集群以及由第二集群自身产生,最后比较第四集群所得到的的值是否24,输出结果
二、程序流程如下:
- 程序调用input函数处理用户输入,并同时生成四个相应的集合
- 调用函数calc,通过其中的list_cross函数产生第二、三、四集群
- 调用函数output输出,并同时删除相同的表达式
- 删除所有集群所占的空间,程序结束
三、主要的数据结构以及算法
为了提高计算精度,使用分数表示每一次计算结果
分数的结构 FRACTION
typedef struct{ int num;//分子 int den;//分母 }FRACTION; //注意分数的符号放在分子上集群链表节点 s_ item
1 typedef char EXPRESS[40]; //存储具体的表达式,如2*3 2 typedef struct s_item{ 3 FRACTION value; //集合的值 如expr为2*3,value.num=6,value.den=1 4 EXPRESS expr; //表达式 5 int flag[4]; //每一个元素代表是否使用相应的数字,如用户输入了1,2,3,4,flag{1,1,0,0},表示 6 //集合含有数字1和2 7 struct s_item* next; //指向下一节点 8 }ITEM,*PITEM;
主要的算法
分数的四则运算:
1.声明
int commonDivisor(int a,int b);//最大公约数 int commonMultiple(int a,int b);//最小公倍数 //公倍数和公约数用于化简和计算分数 FRACTION plus(FRACTION a,FRACTION b);//分数的加法 FRACTION sub(FRACTION a,FRACTION b);//分数的减法 FRACTION multiple(FRACTION a,FRACTION b);//分数乘法 FRACTION division(FRACTION a,FRACTION b);//分数的除法
2.定义
1 //最大公约数 2 int commonDivisor(int a,int b){ 3 int temp=0; 4 while(b!=0){ 5 temp=a%b; 6 a=b; 7 b=temp; 8 } 9 return a; 10 } 11 12 //最小公倍数 13 int commonMultiple(int a,int b){ 14 return a*b/commonDivisor(a,b); 15 } 16 17 18 //分数的加法 19 FRACTION plus(FRACTION a,FRACTION b){ 20 21 if(a.den==b.den){ //分母相同 22 23 a.num=a.num+b.num; 24 }else{ 25 int cm=commonMultiple(a.den,b.den); 26 a.num=a.num*(cm/a.den)+b.num*(cm/b.den); 27 a.den=cm; 28 } 29 30 //简化a,分子分母同除公约数 31 int cm= commonDivisor(abs(a.num),a.den); 32 a.num/=cm; 33 a.den/=cm; 34 35 return a; 36 } 37 38 //分数减法 39 FRACTION sub(FRACTION a,FRACTION b){ 40 41 if(a.den==b.den){ //分母相同 42 43 a.num=a.num-b.num; 44 }else{ 45 int cm=commonMultiple(a.den,b.den); 46 a.num=a.num*(cm/a.den)-b.num*(cm/b.den); 47 a.den=cm; 48 } 49 //简化a,分子分母同除公约数 50 int cm= commonDivisor(abs(a.num),a.den); 51 a.num/=cm; 52 a.den/=cm; 53 54 return a; 55 } 56 57 //分数乘法 58 FRACTION multiple(FRACTION a,FRACTION b){ 59 60 a.num*=b.num; 61 a.den*=b.den; 62 63 int cm= commonDivisor(abs(a.num),a.den); 64 a.num/=cm; 65 a.den/=cm; 66 67 return a; 68 } 69 70 71 //分数的除法 72 FRACTION division(FRACTION a,FRACTION b){ 73 int temp; 74 if(b.num==0){ 75 a.num=0; 76 a.den=0; 77 return a;//不能除0 ,返回分子,分母为0,作为标志 78 }else if(b.num>0){ 79 temp=b.num; 80 b.num=b.den; 81 b.den=temp; 82 }else{ 83 temp =abs(b.num); 84 b.num=b.den; 85 b.den=temp; 86 b.num*=-1; 87 } 88 return multiple(a,b); 89 }
集合之间的加减乘除产生新集合
1.声明
PITEM add(PITEM a,PITEM b); //两个相加 PITEM divide(PITEM a,PITEM b); //两个相除 PITEM mutiply(PITEM a,PITEM b); //两个相乘 PITEM subtract(PITEM a,PITEM b); //两个相减
2.定义
1 PITEM add(PITEM a,PITEM b) //两个相加 2 { 3 4 PITEM x=(struct s_item*)malloc(sizeof(struct s_item)); 5 x->value=plus(a->value,b->value); 6 7 int m; 8 for(m=0;m<4;m++){ 9 x->flag[m]=0; 10 } 11 12 13 int k=0; 14 x->expr[k]='('; 15 int j; 16 for(j=0;a->expr[j]!='