24点游戏大家都知道:4张牌,可以进行+ - * / 四种运算,可以使用括号,每个牌用一次,任意组合构造表达式使结果为24。

扩展问题:n个整数,四种运算,可使用括号,每个数字使用一次,使表达式结果为 k

下面的算法1和算法2都是穷举,只是穷举的方式不一样,以下给出的两个算法代码都可以计算扩展问题。可能是集合操作原因,算法1的速度明显比算法2快

书上分析如下

算法1:

算法1代码如下,我在原来的基础上做了一点改动1、从数组中任选两个数时,保证数对前面没有选择过; 2、通过运算符优先级去除多余的括号;3、选出的两个数相同时,减法和除法只做一次,即只做a-b ,a/b, 不做 b-a,b/a,其中1、3都可以减少冗余计算

调用函数PointGame即可返回表达式结果

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 using namespacestd;9

10 //cards[i]的值是通过表达式expr[i]计算而来11 //且expr的最后一个运算操作lastop[i]

12 bool GameRecur(double cards[], string expr[], charlastop[],13 const int cardsNum, const intresult)14 {15 if(cardsNum == 1)16 {17 if(cards[0] ==result)18 {19 //cout<

20 return true;21 }22 else return false;23 }24 //从已有数中任选两个,计算得到中间结果,并且和剩余的数一起存在cards数组的前25 //cardsNum-1个位置

26 map,bool>selectedPair;27 for(int i = 0; i(cards[i], cards[k]))32 != selectedPair.end() || selectedPair.find(pair

33 (cards[k], cards[i])) !=selectedPair.end() )34 break;35 else

36 {37 selectedPair[pair(cards[i], cards[k])] = 1;38 selectedPair[pair(cards[k], cards[i])] = 1;39 }40 //上面的代码保证选出的数对不重复

41 double a = cards[i], b =cards[k];42 cards[k] = cards[cardsNum-1];43 string expra = expr[i], exprb =expr[k];44 expr[k] = expr[cardsNum-1];45 char lastop_a = lastop[i], lastop_b =lastop[k];46 lastop[k] = lastop[cardsNum-1];47

48 cards[i] = a +b;49 expr[i] = expra + '+' +exprb;50 lastop[i] = '+';51 if(GameRecur(cards, expr, lastop, cardsNum-1, result))52 return true;53

54 cards[i] = a -b;55 if('+' == lastop_b || '-' ==lastop_b)56 expr[i] = expra + '-' + '(' + exprb + ')';57 else expr[i] = expra + '-' +exprb;58 lastop[i] = '-';59 if(GameRecur(cards, expr, lastop, cardsNum-1, result))60 return true;61

62 if(a !=b)63 {64 cards[i] = b -a;65 if('+' == lastop_a || '-' ==lastop_a)66 expr[i] = exprb + '-' + '(' + expra + ')';67 else expr[i] = exprb + '-' +expra;68 lastop[i] = '-';69 if(GameRecur(cards, expr, lastop, cardsNum-1, result))70 return true;71 }72

73 cards[i] = a *b;74 if('-' == lastop_a || '+' ==lastop_a)75 expr[i] = '(' + expra + ')' + '*';76 else expr[i] = expra + '*';77 if('*' == lastop_b || ' ' ==lastop_b)78 expr[i] +=exprb;79 else expr[i] += '(' + exprb + ')';80 lastop[i] = '*';81 if(GameRecur(cards, expr, lastop, cardsNum-1, result))82 return true;83

84 if(b != 0)85 {86 cards[i] = a /b;87 if('-' == lastop_a || '+' ==lastop_a)88 expr[i] = '(' + expra + ')' + '/';89 else expr[i] = expra + '/';90 if(' ' ==lastop_b)91 expr[i] +=exprb;92 else expr[i] += '(' + exprb + ')';93 lastop[i] = '/';94 if(GameRecur(cards, expr, lastop, cardsNum-1, result))95 return true;96 }97

98 if(a != 0 && a!=b)99 {100 cards[i] = b /a;101 if('-' == lastop_b || '+' ==lastop_b)102 expr[i] = '(' + exprb + ')' + '/';103 else expr[i] = exprb + '/';104 if(' ' ==lastop_a)105 expr[i] +=expra;106 else expr[i] += '(' + expra + ')';107 lastop[i] = '/';108 if(GameRecur(cards, expr, lastop, cardsNum-1, result))109 return true;110 }111

112 //把选出来的两个数放回原位

113 cards[i] =a;114 cards[k] =b;115 expr[i] =expra;116 expr[k] =exprb;117 lastop[i] =lastop_a;118 lastop[k] =lastop_b;119 }120 }121 return false;122 }123

124 //cards 输入的牌125 //cardsNum 牌的数目126 //result 想要运算得到的结果

127 string PointGame(int cards[], const int cardsNum, const intresult)128 {129 stringexpr[cardsNum];130 charlastop[cardsNum];131 doublecardsCopy[cardsNum];132 for(int i = 0; i < cardsNum; i++)133 {134 char buf[30];135 sprintf(buf, "%d", cards[i]);136 expr[i] =buf;137 lastop[i] = ' ';//表示cardsCopy[i]是不经过任何运算的原始数据

138 cardsCopy[i] =cards[i];139 }140 if(GameRecur(cardsCopy, expr, lastop, cardsNum, result))141 return expr[0];142 else return "-1";143 }

View Code

对算法1稍作修改可以输出全部的表达式:

1 //------------------------------------------------------------算法1输出所有组合2 //cards[i]的值是通过表达式expr[i]计算而来3 //且expr的最后一个运算操作lastop[i]

4 bool GameRecur_all(double cards[], string expr[], charlastop[],5 const int cardsNum, const intresult)6 {7 if(cardsNum == 1)8 {9 if(cards[0] ==result)10 {11 cout<

18 map,bool>selectedPair;19 bool res = false;20 for(int i = 0; i(cards[i], cards[k]))25 != selectedPair.end() || selectedPair.find(pair

26 (cards[k], cards[i])) !=selectedPair.end() )27 break;28 else

29 {30 selectedPair[pair(cards[i], cards[k])] = 1;31 selectedPair[pair(cards[k], cards[i])] = 1;32 }33 //上面的代码保证选出的数对不重复

34 double a = cards[i], b =cards[k];35 cards[k] = cards[cardsNum-1];36 string expra = expr[i], exprb =expr[k];37 expr[k] = expr[cardsNum-1];38 char lastop_a = lastop[i], lastop_b =lastop[k];39 lastop[k] = lastop[cardsNum-1];40

41 cards[i] = a +b;42 expr[i] = expra + '+' +exprb;43 lastop[i] = '+';44 res = GameRecur_all(cards, expr, lastop, cardsNum-1, result)45 ||res;46

47 cards[i] = a -b;48 if('+' == lastop_b || '-' ==lastop_b)49 expr[i] = expra + '-' + '(' + exprb + ')';50 else expr[i] = expra + '-' +exprb;51 lastop[i] = '-';52 res = GameRecur_all(cards, expr, lastop, cardsNum-1, result) ||res;53

54 if(a !=b)55 {56 cards[i] = b -a;57 if('+' == lastop_a || '-' ==lastop_a)58 expr[i] = exprb + '-' + '(' + expra + ')';59 else expr[i] = exprb + '-' +expra;60 lastop[i] = '-';61 res = GameRecur_all(cards, expr, lastop, cardsNum-1, result)62 ||res;63 }64

65 cards[i] = a *b;66 if('-' == lastop_a || '+' ==lastop_a)67 expr[i] = '(' + expra + ')' + '*';68 else expr[i] = expra + '*';69 if('*' == lastop_b || ' ' ==lastop_b)70 expr[i] +=exprb;71 else expr[i] += '(' + exprb + ')';72 lastop[i] = '*';73 res = GameRecur_all(cards, expr, lastop, cardsNum-1, result)74 ||res;75

76 if(b != 0)77 {78 cards[i] = a /b;79 if('-' == lastop_a || '+' ==lastop_a)80 expr[i] = '(' + expra + ')' + '/';81 else expr[i] = expra + '/';82 if(' ' ==lastop_b)83 expr[i] +=exprb;84 else expr[i] += '(' + exprb + ')';85 lastop[i] = '/';86 res = GameRecur_all(cards, expr, lastop, cardsNum-1, result)87 ||res;88 }89

90 if(a != 0 && a!=b)91 {92 cards[i] = b /a;93 if('-' == lastop_b || '+' ==lastop_b)94 expr[i] = '(' + exprb + ')' + '/';95 else expr[i] = exprb + '/';96 if(' ' ==lastop_a)97 expr[i] +=expra;98 else expr[i] += '(' + expra + ')';99 lastop[i] = '/';100 res = GameRecur_all(cards, expr, lastop, cardsNum-1, result)101 ||res;102 }103

104 //把选出来的两个数放回原位

105 cards[i] =a;106 cards[k] =b;107 expr[i] =expra;108 expr[k] =exprb;109 lastop[i] =lastop_a;110 lastop[k] =lastop_b;111 }112 }113 returnres;114 }115

116 //cards 输入的牌117 //cardsNum 牌的数目118 //result 想要运算得到的结果

119 void PointGame_all(int cards[], const int cardsNum, const intresult)120 {121 stringexpr[cardsNum];122 charlastop[cardsNum];123 doublecardsCopy[cardsNum];124 for(int i = 0; i < cardsNum; i++)125 {126 char buf[30];127 sprintf(buf, "%d", cards[i]);128 expr[i] =buf;129 lastop[i] = ' ';//表示cardsCopy[i]是不经过任何运算的原始数据

130 cardsCopy[i] =cards[i];131 }132 if(GameRecur_all(cardsCopy, expr, lastop, cardsNum, result) == false)133 cout<

View Code

算法2

算法2代码如下,集合用stl中的set表示,代码中变量名保持和书中一致

调用函数PointGame2即可返回表达式结果,调用方式同算法1

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 using namespacestd;9

10 structsetNode11 {12 doubleval;13 string expr;//运算出val的表达式

14 setNode(double v, stringe):val(v),expr(e){}15 setNode(double v, chare[]):val(v),expr(e){}16 bool operator < (const setNode &s)const

17 {18 return val

22 void f(const int i, set s[], const doubleresult)23 {24 int len = sizeof(s)/sizeof(set) - 1;//len = 2^n - 1

25 if(s[i].empty() == true)26 for(int x = 1; x <= i/2; x++)27 if((x&i) ==x)28 {29 set::iterator it1, it2;30 //s[i] U= fork(s[x] ,s[i-x])

31 for(it1 = s[x].begin(); it1 != s[x].end(); it1++)32 for(it2 = s[i-x].begin(); it2 != s[i-x].end(); it2++)33 {34 stringexpr;35 doubletempresult;36 tempresult = it1->val + it2->val;37 expr = '(' + it1->expr + '+' + it2->expr + ')';38 s[i].insert(setNode(tempresult, expr));39 //计算f[2^n-1]时,若计算好了结果则可以停止

40 if(i == len && tempresult == result)return;41

42

43 tempresult = it1->val - it2->val;44 expr = '(' + it1->expr + '-' + it2->expr + ')';45 s[i].insert(setNode(tempresult, expr));46 if(i == len && tempresult == result)return;47 if(it1->val != it2->val)48 {49 tempresult = it2->val - it1->val;50 expr = '(' + it2->expr + '-' + it1->expr + ')';51 s[i].insert(setNode(tempresult, expr));52 if(i == len && tempresult == result)return;53 }54

55 tempresult = it1->val * it2->val;56 expr = '(' + it1->expr + '*' + it2->expr + ')';57 s[i].insert(setNode(tempresult, expr));58 if(i == len && tempresult == result)return;59

60 if(it2->val != 0)61 {62 tempresult = it1->val / it2->val;63 expr = '(' + it1->expr + '/' + it2->expr + ')';64 s[i].insert(setNode(tempresult, expr));65 if(i == len && tempresult == result)return;66 }67 if(it1->val != it2->val && it1->val != 0)68 {69 tempresult = it2->val / it1->val;70 expr = '(' + it2->expr + '/' + it1->expr + ')';71 s[i].insert(setNode(tempresult, expr));72 if(i == len && tempresult == result)return;73 }74 }75 }76 }77

78 string PointGame2(int cards[], const int cardsNum, const intresult)79 {80 int len = 1< S[len]; //对应文章中的数组S82 //初始化只有一个元素的子集,j = 2^i,即只有一个2进制位是1

83 for(int i = 0, j = 1; i < cardsNum; i++, j = j<<1)84 {85 char buf[30];86 sprintf(buf, "%d", cards[i]);87 S[j].insert(setNode(cards[i],buf));88 }89 for(int i = 1; i <= len - 1; i++)90 f(i, S, result);91 for(set::iterator it = S[len-1].begin();92 it != S[len-1].end(); it++)93 {94 if(it->val ==result)95 return it->expr;96 }97 return "-1";98 }

View Code

24点游戏java代码 中国开源社区_编程之美 1.16 24点游戏相关推荐

  1. 24点游戏java代码 中国开源社区_编程实现一个有GUI的24点游戏

    24点是指从去除大小王后的52张扑克牌中任取 4 张,通过「加.减.乘.除」四则运算得到 24.是一个历史悠久的趣味小游戏. <数据化管理>书中在测试数据敏感度章节提到一个细节" ...

  2. 问中国开源社区 谁主沉浮?

    问中国开源社区 谁主沉浮? 8月24号有幸参加了"2006开源中国 开源世界 暨开放标准.开放架构.开源生态系统和应用解决方案高峰论坛".会上各位大师都发表了自己对Open Sou ...

  3. 麒麟软件副总裁李震宁:中国开源社区是操作系统破局的土壤

    整理 | 小雨青年 "开源"这片培育新技术的土地,孕育出了无数为科技奋斗的软件开发者.麒麟软件通过中国开源社区自身的力量和资源发展壮大,也以自身的强健让这片科技的土地显得更加丰沃. ...

  4. 中国开源社区的发展状况

    中国开源社区的发展状况 近年来,伴随开源运动在中国的推进,开源社区也取得很大发展.开源社区的建设对促进中国开源事业与国际接轨具有深远影响,有利于进一步推进与国际开源社区的交流合作,了解并学习国际前沿的 ...

  5. 开源的未来 10 年:中国开源社区建立是关键

    [CSDN 编者按]从 Eric Raymond 在自由软件的范畴下进一步提出 Open Source 开源软件至今,已经过去 30 余年,今天,开源不仅完全渗透互联网,更成为众多 IT 公司的基石. ...

  6. 五子棋游戏Java代码简单实现(含活动图和类图设计)

    五子棋游戏Java代码简单实现(含活动图和类图设计) 文章目录 五子棋游戏Java代码简单实现(含活动图和类图设计) 活动图设计 类图设计 代码实现 总结 OOA和OOD设计 代码设计 可改进部分 活 ...

  7. java猜拳游戏代码_猜拳游戏 - java代码库 - 云代码

    [java]代码库public class Computer { String name; int score; public int showfist(){ int quan; quan=(int) ...

  8. 21点 小游戏 java代码_基于Java的21点扑克游戏的实现

    在上次写的比较牌点的扑克游戏上Java扑克游戏(多人多牌数比较游戏)的实现中,添加21点游戏规则,实现21点牌类游戏.具体实现步骤如下:[需要源代码的留QQ,大家一起探讨探讨哈,谢谢啦!] 抽象出规则 ...

  9. 贪吃蛇小游戏--Java代码

    贪吃蛇游戏 图纸设计 按帧动 静态页面绘制 让小蛇动起来 吃豆豆 积分展示 展望 难点:计算坐标 package comleo.snake;import javax.swing.*;public cl ...

最新文章

  1. 高并发:RocketMQ 削峰实战!
  2. Spring小知识——profile配置
  3. Visual Studio 2005 插件编程(代码行数统计插件)之一
  4. C++中virtual关键字的用法
  5. swift 闭包的使用
  6. 面试:Zookeeper
  7. 交换机 链路层无法udp通讯_一文读懂计算机底层网络原理,包括TCP、UDP、header,什么是包、帧、段等关键问题...
  8. 微信扫码免密登陆第三方应用平台
  9. yyuc php,YYUC框架与YYUC手册资料下载 | 无名
  10. Oracle Certified
  11. 微信nickname乱码 php,CSV中微信名字乱码 问题
  12. 关于快速学习一项新技术或新领域的一些个人思维习惯与思想总结
  13. 字体图标iocnfont
  14. 语音专题第一讲,麦克风阵列的语音信号处理技术
  15. import()函数和import语句
  16. 影响人类!写入历史!疫情年最值得铭记的6个大事件
  17. 国王将金币作为工资,发放给忠诚的骑士。 问题 G: 金币
  18. Android 色板
  19. js时间戳转换年月日
  20. Fritzing软件绘制Arduino面包板接线图传感器模块查找元件添加库文件

热门文章

  1. python 两个变量同时循环_python基础篇(子非鱼)
  2. 如何转换为系统应用_如何将AVI转换为GIF
  3. 1 为发现 php,magento 1.8.1中发现sitemap模块的一个bug
  4. 现代ups电源及电路图集_2020山特UPS电源自动开机200KVA实力
  5. android content provider线程安全,Android ContentProvider的线程安全(二)
  6. html 按键hover,按钮hover效果
  7. 计算机组成原理固件,计算机组成原理(A卷)
  8. 最新Discuz验证码和PhpWind验证码的识别
  9. Win 2012 OS 安装.Net Framework 3.5
  10. 20、Tabs底部导航栏