为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > 经典24点算法[优质文档]

经典24点算法[优质文档]

2017-11-08 8页 doc 22KB 34阅读

用户头像

is_321635

暂无简介

举报
经典24点算法[优质文档]经典24点算法[优质文档] 经典24点程序算法 一、 概述 算24点:任意给定四个整数,用加、减、乘、除以及适当的括号连接,无论顺序,使计算结果为24,也可能根本就无解。如何用程序简单实现找到算式是程序初学者关注的问题,百度上可以搜到许多这样的文章,有递归法、回溯法、穷举法。但穷举法最为简单、易于理解。 二、 算法 穷举法就是把四个数字的所有运算式进行尝试计算,要设法把所有排列一点不差地穷举出,一、是四个整数位置的排列,用0,1,2,3表示位置,排列是不能重复的,所以有P(4,4)种情况,即4~=4*3*2*1=24种...
经典24点算法[优质文档]
经典24点算法[优质文档] 经典24点程序算法 一、 概述 算24点:任意给定四个整数,用加、减、乘、除以及适当的括号连接,无论顺序,使计算结果为24,也可能根本就无解。如何用程序简单实现找到算式是程序初学者关注的问题,百度上可以搜到许多这样的文章,有递归法、回溯法、穷举法。但穷举法最为简单、易于理解。 二、 算法 穷举法就是把四个数字的所有运算式进行尝试计算,要设法把所有排列一点不差地穷举出,一、是四个整数位置的排列,用0,1,2,3表示位置,排列是不能重复的,所以有P(4,4)种情况,即4~=4*3*2*1=24种;二、是三个运算符的变化,每个运算符为+-*/ ,可以相同,所以,有4*4*4=64种; 三、三个运算符的优先级,就是括号位置的变化,可能性为P(3,3)-1=6-1=5种;所以,表达式的可能性为:24*64*5=7680种,C语言程序把这么多表达式都计算一遍,几乎不到1毫秒毫不费劲, 可见电脑的运行速度之快。 四个数位置的排列,可用四重循环实现,四个循环变量i1,i2,i3,i4对应数组下标的变化, 不许它们之间相等,四个数放在数组v[0]、v[1]、v[2]、v[3]: for (int i1=0;i1<4;i1++) for (int i2=0;i2<4;i2++) if (i2!=i1) // 循环变量不许相同 for (int i3=0;i3<4;i3++) if (i3!=i2 && i3!=i1) // 循环变量不许相同,&& 是“并且” for (int i4=0;i4<4;i4++) if (i4!=i3 && i4!=i2 && i4!=i1) // 循环变量不许相同 { // v[i1],v[i2],v[i3],v[i4] 就是排列的结果,共有4!=24 种 , 三个运算符的变化,可用三重循环实现,三个循环变量 f1,f2,f3对应位置的变化,允许相同,运算符放在数组op[0]、op[1]、op[2]、op[3]中: for (int f1=0;f1<4;f1++) // 三重循环对运算符穷举 for (int f2=0;f2<4;f2++) for (int f3=0;f3<4;f3++) // 运算符 f1,f2,f3 { // op[f1],op[f2],op[f3]就是排列结果,共有4*4*4=64 种 } b ? c ? d 上面两种排列组合后,四个数及运算符排列顺序就是形如:a ? v[i1],op[f1],v[i2],op[f2],v[i3],op[f3],v[i4] 但运算符有优先级,一般是用括号表示。我们可以规定运算符的优先级来代替括号。设四张牌为a、b、c、d,运算符为?、?、?,表达式为a ? b ? c ? d。 这3个运算符的运算顺序有3~=6种,分别是: 1(??? 2.??? 3.??? 4.??? 5.??? 6.??? 等价的表达式分别是: 1.((a?b?)c?)d 2.(a?b)?(c?d) 3.(a?(b?c))?d 4.a?((b?c)?d) 5.(a?b)?(c?d) 6. a?(b?(c?d)) 显然,2和5是相同的,因此只考虑5种情况。这样,括号的问题就解决了。为了简单起见,这五种情况未用循环,大大减化了程序的复杂性,更易于理解。 对这组排列逐一进行运算,看是否是24,就可以得到最终所有式子了。在运算过程中除法的特殊性——除数不能为零。因为可能会用到除法,所以要考虑精度问题,这里通过结果减去24取绝对值与一个接近0的小数(如0.001)比较,如小于它,即可判定结果是24。 三、 程序 有了上面的算法,这个程序很简单,只用了最简单的基本语句,你可以改成任何程序语言: /*------------------------------------------------------------* | 24点(穷举法)算法程序 V1.0 | | By 叶宏 2012.6.27 | *------------------------------------------------------------*/ #include "stdio.h" // 输入输出定义 double cal(double a,double b,int op) // op: 0:+,1:-,2:*,3:/ { switch (op) // +-x/ 运算 { case 0: return(a+b); case 1: return(a-b); case 2: return(a*b); } if (b==0.0) // 分母为0 return(999.0); else return(a/b); } bool isEqual(double d1,double d2) // 两个浮点数是否近似相等 { double d=d1-d2; if (d<0) d=-d; // 求绝对值 return(d<=0.001); } void D24(int v0,int v1,int v2,int v3) // 穷举法求24点 { ','*','/'}; // +:0 -:1 *:2 /:3 char op[4]={'+','- int v[4]; // 输入四整数 v[0]=v0; v[1]=v1; v[2]=v2; v[3]=v3; //-----------四重循环开始穷举四个数字的位置: 4!=24 种-------------------------- int count=0; // 计数成功次数 for (int i1=0;i1<4;i1++) for (int i2=0;i2<4;i2++) // 四重循环对四个数穷举 if (i2!=i1) for (int i3=0;i3<4;i3++) if (i3!=i2 && i3!=i1) for (int i4=0;i4<4;i4++) if (i4!=i3 && i4!=i2 && i4!=i1) { //-----------三重循环开始穷举三个运算符: 4X4X4=64 种--------------------------- for (int f1=0;f1<4;f1++) // 三重循环对运算符穷举 for (int f2=0;f2<4;f2++) for (int f3=0;f3<4;f3++) // 运算符 f1,f2,f3 { // 对运算优先级直接列举(5种) //-----------未用循环,直接穷举三个运算符的优先级: 3!-1=5种-------------------- double t1,t2,t3; // 存放计算的中间值 // 第1种情况 ((a 。b)。c)。d : t1=cal(v[i1],v[i2],f1); t2=cal(t1,v[i3],f2); t3=cal(t2,v[i4],f3); if (isEqual(t3,24)) // 运算后是否为24 { char *fs="((%d%c%d)%c%d)%c%d=24\n"; printf(fs,v[i1],op[f1],v[i2],op[f2],v[i3],op[f3],v[i4]); count++; } // 第2种情况(a 。b)。(c。 d) 开始计算 : t1=cal(v[i1],v[i2],f1); t2=cal(v[i3],v[i4],f3); t3=cal(t1,t2,f2); if (isEqual(t3,24)) // 运算后是否为24 { char *fs="(%d%c%d)%c(%d%c%d)=24\n"; printf(fs,v[i1],op[f1],v[i2],op[f2],v[i3],op[f3],v[i4]); count++; } // 第3种情况 (a。(b。c))。d 开始计算 : t1=cal(v[i2],v[i3],f2); t2=cal(v[i1],t1,f1); t3=cal(t2,v[i4],f3); if (isEqual(t3,24)) // 运算后是否为24 { char *fs="(%d%c(%d%c%d))%c%d=24\n"; printf(fs,v[i1],op[f1],v[i2],op[f2],v[i3],op[f3],v[i4]); count++; } // 第4种情况 a。((b。c)。d ) 开始计算: t1=cal(v[i2],v[i3],f2); t2=cal(t1,v[i4],f3); t3=cal(v[i1],t2,f1); if (isEqual(t3,24)) // 运算后是否为24 { char *fs="%d%c((%d%c%d)%c%d)=24\n"; printf(fs,v[i1],op[f1],v[i2],op[f2],v[i3],op[f3],v[i4]); count++; } // 第5种情况 a。(b。(c。d)) 开始计算: t1=cal(v[i3],v[i4],f3); t2=cal(v[i2],t1,f2); t3=cal(v[i1],t2,f1); if (isEqual(t3,24)) // 运算后是否为24 { char *fs="%d%c(%d%c(%d%c%d))=24\n"; printf(fs,v[i1],op[f1],v[i2],op[f2],v[i3],op[f3],v[i4]); count++; } } } //-------------- 穷举结束: 共 24*64*5=7680 种表达式 --------------------------- if (count==0) printf("\n%d,%d,%d,%d 不能算出24.",v0,v1,v2,v3); else printf("\n共找到算式 %d 条.",count); } void main() { int v0,v1,v2,v3; printf("输入四个整数: "); scanf("%d %d %d %d",&v0,&v1,&v2,&v3); D24(v0,v1,v2,v3); getchar(); getchar();
/
本文档为【经典24点算法[优质文档]】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索