400字范文,内容丰富有趣,生活中的好帮手!
400字范文 > 24点游戏c语言链表做法 C语言实现24点程序(示例代码)

24点游戏c语言链表做法 C语言实现24点程序(示例代码)

时间:2022-04-22 13:04:29

相关推荐

24点游戏c语言链表做法 C语言实现24点程序(示例代码)

一、简介

本程序的思想和算法来自于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 structs_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,intb){3 int temp=0;4 while(b!=0){5 temp=a%b;6 a=b;7 b=temp;8 }9 returna;10 }11

12 //最小公倍数

13 int commonMultiple(int a,intb){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 returna;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 returna;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 returna;68 }69

70

71 //分数的除法

72 FRACTION division(FRACTION a,FRACTION b){73 inttemp;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 returnmultiple(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(structs_item));5 x->value=plus(a->value,b->value);6

7 intm;8 for(m=0;m<4;m++){9 x->flag[m]=0;10 }11

12

13 int k=0;14 x->expr[k]=‘(‘;15 intj;16 for(j=0;a->expr[j]!=‘\0‘;j++){17 x->expr[++k]=a->expr[j];18 }19 x->expr[++k]=‘+‘;20 for(j=0;b->expr[j]!=‘\0‘;j++){21 x->expr[++k]=b->expr[j];22 }23 x->expr[++k]=‘)‘;24 x->expr[++k]=‘\0‘;25

26

27 int i=0;28 for(i=0;i<4;i++){29 if(a->flag[i]==1){30 x->flag[i]=1;31 }32

33 if(b->flag[i]==1){34 x->flag[i]=1;35 }36

37

38 }39

40 x->next=NULL;41

42 returnx;43 }44

45

46 PITEM divide(PITEM a,PITEM b){ //集合相除

47 PITEM x=(struct s_item*)malloc(sizeof(structs_item));48 x->value=division(a->value,b->value);49

50 intm;51 for(m=0;m<4;m++){52 x->flag[m]=0;53 }54 if(x->value.num==0&&x->value.den==0){55 free(x);56 returnNULL;57 }58

59 int k=0;60 x->expr[k]=‘(‘;61 intj;62 for(j=0;a->expr[j]!=‘\0‘;j++){63 x->expr[++k]=a->expr[j];64 }65 x->expr[++k]=‘/‘;66 for(j=0;b->expr[j]!=‘\0‘;j++){67 x->expr[++k]=b->expr[j];68 }69 x->expr[++k]=‘)‘;70 x->expr[++k]=‘\0‘;71

72 int i=0;73 for(i=0;i<4;i++){74 if(a->flag[i]==1){75 x->flag[i]=1;76 }77

78 if(b->flag[i]==1){79 x->flag[i]=1;80 }81

82

83 }84

85 x->next=NULL;86 returnx;87 }88 PITEM mutiply(PITEM a,PITEM b)//两个相乘

89 {90 PITEM x=(struct s_item*)malloc(sizeof(structs_item));91 x->value=multiple(a->value,b->value);92 intm;93 for(m=0;m<4;m++){94 x->flag[m]=0;95 }96 int k=0;97 x->expr[k]=‘(‘;98 intj;99 for(j=0;a->expr[j]!=‘\0‘;j++){100 x->expr[++k]=a->expr[j];101 }102 x->expr[++k]=‘*‘;103 for(j=0;b->expr[j]!=‘\0‘;j++){104 x->expr[++k]=b->expr[j];105 }106 x->expr[++k]=‘)‘;107 x->expr[++k]=‘\0‘;108

109 int i=0;110 for(i=0;i<4;i++){111 if(a->flag[i]==1){112 x->flag[i]=1;113 }114

115 if(b->flag[i]==1){116 x->flag[i]=1;117 }118

119

120 }121

122 x->next=NULL;123 returnx;124 }125

126

127 PITEM subtract(PITEM a,PITEM b){ //相减

128 PITEM x=(struct s_item*)malloc(sizeof(structs_item));129 x->value=sub(a->value,b->value);130 intm;131 for(m=0;m<4;m++){132 x->flag[m]=0;133 }134 int k=0;135 x->expr[k]=‘(‘;136 intj;137 for(j=0;a->expr[j]!=‘\0‘;j++){138 x->expr[++k]=a->expr[j];139 }140 x->expr[++k]=‘-‘;141 for(j=0;b->expr[j]!=‘\0‘;j++){142 x->expr[++k]=b->expr[j];143 }144 x->expr[++k]=‘)‘;145 x->expr[++k]=‘\0‘;146

147 int i=0;148 for(i=0;i<4;i++){149 if(a->flag[i]==1){150 x->flag[i]=1;151 }152

153 if(b->flag[i]==1){154 x->flag[i]=1;155 }156

157

158 }159

160 x->next=NULL;161 returnx;162 }

View Code

核心代码

产生新集群 list_cross

1 //比较集群之间是否有相同数字

2 intcmp(PITEM left,PITEM right){3 inti;4 for(i=0;i<4;i++){5 if(left->flag[i]==1&&right->flag[i]==1){6 return 1;7 }8 }9 return 0;10 }11

12 //结合两个集群产生下一个集群

13 voidlist_cross(PITEM left,PITEM right,PITEM result){14

15 PITEM p,q;16 for(p=left->next;p!=NULL;p=p->next){ //循环调用两个集群中所有集合

17 for(q=right->next;q!=NULL;q=q->next)18 if(cmp(p,q)==0){ //只有两集合不含相同数字才运算

19 PITEM temp=NULL;20 if((temp=add(p,q))!=NULL){21 temp->next=result->next;22 result->next=temp;23 }24 if((temp=subtract(p,q))!=NULL){25 temp->next=result->next;26 result->next=temp;27 }28 if((temp=divide(p,q))!=NULL){29 temp->next=result->next;30 result->next=temp;31 }32 if((temp=mutiply(p,q))!=NULL){33 temp->next=result->next;34 result->next=temp;35 }36

37 }38 }39 }

因为用户有可能输入相同的数字,所以要消除相同的表达式:

消除重复表达式

1 PITEM p=p4_head->next; //p指向第四集群的头结点,第四集群即最后四个数字都已经使用的集合2

3 //消除重复的表达式

4

5 PITEM q,pre;6 for(;p!=NULL;p=p->next){7 for(q=p->next,pre=p;q!=NULL;){8 if(strcmp(p->expr,q->expr)==0){9

10 pre->next=q->next;11 PITEM temp=q; //pre为p的前一个节点

12 q=q->next;13

14 free(temp);//消失重复点;

15 temp=NULL;16

17 }else{18 q=q->next;19 pre=pre->next;20 }21 }22 }

判断集合的值,输出结果

//输出

p=p4_head->next;while(p!=NULL){if(p->value.num==24&&p->value.den==1){

puts(p->expr);

}

p=p->next;

}

四、运行

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。