一、简介

本程序的思想和算法来自于C语言教材后的实训项目,程序通过用户输入四个整数计算出能够通过加减乘除得到数字24的所有表达式,程序的设计有别于一般通过穷举实现的方式,效率得到提高。算法介绍如下:

如用户输入1,2,3,4四个数字,先将其看成四个集合即{1},{2},{3},{4},整个叫做第一集群,后通过任意两个集合加减乘除{1,2},{1,3},{1,4},{2,3},{2,4},{3,4}六个集合叫做第二集群,而第三集群由第一集群和第二集群产生,而第四集群可由第一集群和第三集群以及由第二集群自身产生,最后比较第四集群所得到的的值是否24,输出结果


二、程序流程如下:

  1. 程序调用input函数处理用户输入,并同时生成四个相应的集合
  2. 调用函数calc,通过其中的list_cross函数产生第二、三、四集群
  3. 调用函数output输出,并同时删除相同的表达式
  4. 删除所有集群所占的空间,程序结束

三、主要的数据结构以及算法

为了提高计算精度,使用分数表示每一次计算结果

分数的结构 FRACTION

typedef struct{
int num;//分子
int den;//分母
}FRACTION; //注意分数的符号放在分子上

集群链表节点 s_ item

 typedef char EXPRESS[]; //存储具体的表达式,如2*3
typedef struct s_item{
FRACTION value; //集合的值 如expr为2*3,value.num=6,value.den=1
EXPRESS expr; //表达式
int flag[]; //每一个元素代表是否使用相应的数字,如用户输入了1,2,3,4,flag{1,1,0,0},表示
//集合含有数字1和2
struct s_item* next; //指向下一节点
}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.定义

 //最大公约数
int commonDivisor(int a,int b){
int temp=;
while(b!=){
temp=a%b;
a=b;
b=temp;
}
return a;
} //最小公倍数
int commonMultiple(int a,int b){
return a*b/commonDivisor(a,b);
} //分数的加法
FRACTION plus(FRACTION a,FRACTION b){ if(a.den==b.den){ //分母相同 a.num=a.num+b.num;
}else{
int cm=commonMultiple(a.den,b.den);
a.num=a.num*(cm/a.den)+b.num*(cm/b.den);
a.den=cm;
} //简化a,分子分母同除公约数
int cm= commonDivisor(abs(a.num),a.den);
a.num/=cm;
a.den/=cm; return a;
} //分数减法
FRACTION sub(FRACTION a,FRACTION b){ if(a.den==b.den){ //分母相同 a.num=a.num-b.num;
}else{
int cm=commonMultiple(a.den,b.den);
a.num=a.num*(cm/a.den)-b.num*(cm/b.den);
a.den=cm;
}
//简化a,分子分母同除公约数
int cm= commonDivisor(abs(a.num),a.den);
a.num/=cm;
a.den/=cm; return a;
} //分数乘法
FRACTION multiple(FRACTION a,FRACTION b){ a.num*=b.num;
a.den*=b.den; int cm= commonDivisor(abs(a.num),a.den);
a.num/=cm;
a.den/=cm; return a;
} //分数的除法
FRACTION division(FRACTION a,FRACTION b){
int temp;
if(b.num==){
a.num=;
a.den=;
return a;//不能除0 ,返回分子,分母为0,作为标志
}else if(b.num>){
temp=b.num;
b.num=b.den;
b.den=temp;
}else{
temp =abs(b.num);
b.num=b.den;
b.den=temp;
b.num*=-;
}
return multiple(a,b);
}

集合之间的加减乘除产生新集合

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.定义

 PITEM add(PITEM a,PITEM b) //两个相加
{ PITEM x=(struct s_item*)malloc(sizeof(struct s_item));
x->value=plus(a->value,b->value); int m;
for(m=;m<;m++){
x->flag[m]=;
} int k=;
x->expr[k]='(';
int j;
for(j=;a->expr[j]!='\0';j++){
x->expr[++k]=a->expr[j];
}
x->expr[++k]='+';
for(j=;b->expr[j]!='\0';j++){
x->expr[++k]=b->expr[j];
}
x->expr[++k]=')';
x->expr[++k]='\0'; int i=;
for(i=;i<;i++){
if(a->flag[i]==){
x->flag[i]=;
} if(b->flag[i]==){
x->flag[i]=;
} } x->next=NULL; return x;
} PITEM divide(PITEM a,PITEM b){ //集合相除
PITEM x=(struct s_item*)malloc(sizeof(struct s_item));
x->value=division(a->value,b->value); int m;
for(m=;m<;m++){
x->flag[m]=;
}
if(x->value.num==&&x->value.den==){
free(x);
return NULL;
} int k=;
x->expr[k]='(';
int j;
for(j=;a->expr[j]!='\0';j++){
x->expr[++k]=a->expr[j];
}
x->expr[++k]='/';
for(j=;b->expr[j]!='\0';j++){
x->expr[++k]=b->expr[j];
}
x->expr[++k]=')';
x->expr[++k]='\0'; int i=;
for(i=;i<;i++){
if(a->flag[i]==){
x->flag[i]=;
} if(b->flag[i]==){
x->flag[i]=;
} } x->next=NULL;
return x;
}
PITEM mutiply(PITEM a,PITEM b)//两个相乘
{
PITEM x=(struct s_item*)malloc(sizeof(struct s_item));
x->value=multiple(a->value,b->value);
int m;
for(m=;m<;m++){
x->flag[m]=;
}
int k=;
x->expr[k]='(';
int j;
for(j=;a->expr[j]!='\0';j++){
x->expr[++k]=a->expr[j];
}
x->expr[++k]='*';
for(j=;b->expr[j]!='\0';j++){
x->expr[++k]=b->expr[j];
}
x->expr[++k]=')';
x->expr[++k]='\0'; int i=;
for(i=;i<;i++){
if(a->flag[i]==){
x->flag[i]=;
} if(b->flag[i]==){
x->flag[i]=;
} } x->next=NULL;
return x;
} PITEM subtract(PITEM a,PITEM b){ //相减
PITEM x=(struct s_item*)malloc(sizeof(struct s_item));
x->value=sub(a->value,b->value);
int m;
for(m=;m<;m++){
x->flag[m]=;
}
int k=;
x->expr[k]='(';
int j;
for(j=;a->expr[j]!='\0';j++){
x->expr[++k]=a->expr[j];
}
x->expr[++k]='-';
for(j=;b->expr[j]!='\0';j++){
x->expr[++k]=b->expr[j];
}
x->expr[++k]=')';
x->expr[++k]='\0'; int i=;
for(i=;i<;i++){
if(a->flag[i]==){
x->flag[i]=;
} if(b->flag[i]==){
x->flag[i]=;
} } x->next=NULL;
return x;
}

核心代码

产生新集群 list_cross

 //比较集群之间是否有相同数字
int cmp(PITEM left,PITEM right){
int i;
for(i=;i<;i++){
if(left->flag[i]==&&right->flag[i]==){
return ;
}
}
return ;
} //结合两个集群产生下一个集群
void list_cross(PITEM left,PITEM right,PITEM result){ PITEM p,q;
for(p=left->next;p!=NULL;p=p->next){ //循环调用两个集群中所有集合
for(q=right->next;q!=NULL;q=q->next)
if(cmp(p,q)==){ //只有两集合不含相同数字才运算
PITEM temp=NULL;
if((temp=add(p,q))!=NULL){
temp->next=result->next;
result->next=temp;
}
if((temp=subtract(p,q))!=NULL){
temp->next=result->next;
result->next=temp;
}
if((temp=divide(p,q))!=NULL){
temp->next=result->next;
result->next=temp;
}
if((temp=mutiply(p,q))!=NULL){
temp->next=result->next;
result->next=temp;
} }
}
}

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

消除重复表达式

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

      //消除重复的表达式 

      PITEM q,pre;
for(;p!=NULL;p=p->next){
for(q=p->next,pre=p;q!=NULL;){
if(strcmp(p->expr,q->expr)==){ pre->next=q->next;
PITEM temp=q; //pre为p的前一个节点
q=q->next; free(temp);//消失重复点;
temp=NULL; }else{
q=q->next;
pre=pre->next;
}
}
}

判断集合的值,输出结果

     //输出
p=p4_head->next;
while(p!=NULL){
if(p->value.num==&&p->value.den==){ puts(p->expr); } p=p->next;
}

四、运行

               

源代码地址:C语言实现24点src

C语言实现24点程序的更多相关文章

  1. C语言学习书籍推荐《学通C语言的24堂课》下载

    下载地址:点我 编辑推荐 <学通C语言的24堂课>:用持续激励培养良好习惯以良好习惯铸就伟大梦想——致亲爱的读者朋友在开始学习<学通C语言的24堂课>的同时,强烈建议读者朋友同 ...

  2. C语言之简易了解程序环境

    C语言之简易了解程序环境 大纲: 程序的翻译环境 预编译 编译 汇编 链接 程序的运行环境 在ANSI C的任何一种实现中,存在两个不同的环境. 第1种是翻译环境,在这个环境中源代码被转换为可执行的机 ...

  3. 基于php基础语言编写的小程序之计算器

    基于php基础语言编写的小程序之计算器 需求:在输入框中输入数字进行加.减.乘.除运算(html+php) 思路: 1首先要创建输入数字和运算符的输入框,数字用input的text属性,运算符用sel ...

  4. 利用Scala语言开发Spark应用程序

    Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可 以阅读网络教程A Scala Tutorial for Ja ...

  5. SAS进阶《深入解析SAS》之开发多语言支持的SAS程序

    SAS进阶<深入解析SAS>之开发多语言支持的SAS程序 1. 多语言支持的应用程序是指该程序在世界给第使用时,其能够处理的数据,以及处理数据的方式.信息展现的方式都符合当地的语言.文化习 ...

  6. JAVA 基础编程练习题24 【程序 24 根据输入求输出】

    24 [程序 24 根据输入求输出] 题目:给一个不多于 5 位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. package cskaoyan; public class cskaoya ...

  7. [转载] 使用C/C++语言编写基于DSP程序的注意事项

    原文地址:『转』使用C/C++语言编写基于DSP程序的注意事项作者:skysmile   1.不影响执行速度的情况下,可以使用c或c/c++语言提供的函数库,也可以自己设计函数,这样更易于使用“裁缝师 ...

  8. 程序员之---C语言细节24(段错误、类型提升、sizeof &#39;A&#39;)

    主要内容:段错误.类型提升.sizeof  'A' #include <stdio.h> int main() { union test{ char a[10]; int b; }u; i ...

  9. 平方根的C语言实现(三) ——最终程序实现

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7223254.html 作者:窗户 Q ...

随机推荐

  1. 驳《编码规范是技术上的遮羞布》自由发挥==摆脱编码规范?X

    引子: 看了一坨文字<编码规范是技术上的遮羞布>,很是上火,见人见智,本是无可厚非,却深感误人子弟者众.原文观点做一个简单的提炼: 1.扔掉编码规范吧,让程序员自由发挥,你会得到更多的好处 ...

  2. BASIC-23_蓝桥杯_芯片测试

    思路: 1.当测试与被测试的芯片全部可以互相测试时,为好芯片; 示例代码: #include <stdio.h>#define N 20 int main(void){ int n = 0 ...

  3. StringIO-将字符串当做文件处理

    StringIO将字符串当做文件处理,十分方便 >>> from StringIO import StringIO >>> file_like_string = S ...

  4. 数据库启动失败:The server quit without updating PID file

    1.可能是/usr/local/mysql/data/mysql.pid文件没有写的权限解决方法 :给予权限,执行 “chown -R mysql:mysql /var/data” “chmod -R ...

  5. maven学习(5)-Maven 聚合与继承特性

    接着上面的项目, 继承和聚合为了统一管理: 聚合: 有些项目中有很多小模块,可以合并到一起,将多个子项目可以统一管理,可以对user-dao,user-service进行统一管理(maven clea ...

  6. 修改phpMYadmin 链接其他数据库地址的方法

    找到phpmyadmin的文件 修改 config.inc.php 文件 框红的地方修改成你需要链接的数据库信息 重启环境,再次访问 phpmyadmin 地址即可

  7. 小甲鱼-003 python插曲值变量和字符串

    变量名就像现实生活人们的名字,把一个值赋值给一个名字时,他会存储在内存中,称之为变量variable,在大多数语言中,都把这种行为成为"给变量赋值"或"把值存储在变量中& ...

  8. [UE4]使机器人受伤

  9. securecrt8注册码

    securecrt8注册码,两个可用 Name:meisiCompany:TEAM ZWTSerial Number:03-14-367662License Key:ACCFAX R9FHJ7 QZV ...

  10. centos 7 mount usb hard disk(ntfs format)

    1. yum install -y epel-release* 2. yum install -y ntfs-3g 3. 命令:fdisk -l (查看磁盘分区信息) [root@devserverg ...