C++实现24点游戏
来源:互联网 发布:mac airplay显示关闭 编辑:程序博客网 时间:2024/05/17 23:53
1. 算法思路
(1)首先穷举的可行性问题。我把表达式如下分成三类
1、 无括号的简单表达式。
2、 有一个括号的简单表达式。
3、 有两个括号的较复4,杂表达式。
穷举的开始我对给出的四个数进行排列,其可能的种数为4*3*2*1=24。我利用一个嵌套函数实现四个数的排列
(2)那么作为栈的著名应用,表达式的计算可以有两种方法。
第一种方法:
首先建立两个栈,操作数栈OVS和运算符栈OPS。其中,操作数栈用来记忆表达式中的操作数,其栈顶指针为topv,初始时为空,即topv=0;运算符栈用来记忆表达式中的运算符,其栈顶指针为topp,初始时,栈中只有一个表达式结束符,即topp=1,且OPS(1)=‘;’。此处的‘;’即表达式结束符。
然后自左至右的扫描待处理的表达式,并假设当前扫描到的符号为W,根据不同的符号W做如下不同的处理:
1、若W为操作数
2、则将W压入操作数栈OVS
3、且继续扫描下一个字符
4、若W为运算符
5、则根据运算符的性质做相应的处理:
(1)、若运算符为左括号或者运算符的优先级大于运算符栈栈顶的运算符(即OPS(top)),则将运算符W压入运算符栈OPS,并继续扫描下一个字符。
(2)、若运算符W为表达式结束符‘;’且运算符栈栈顶的运算符也为表达式结束符(即OPS(topp)=’;’),则处理过程结束,此时,操作数栈栈顶元素(即OVS(topv))即为表达式的值。
(3)、若运算符W为右括号且运算符栈栈顶的运算符为左括号(即OPS(topp)=’(‘),则将左括号从运算符栈谈出,且继续扫描下一个符号。
(4)、若运算符的右不大于运算符栈栈顶的运算符(即OPS(topp)),则从操作数栈OVS中弹出两个操作数,设先后弹出的操作数为a、b,再从运算符栈OPS中弹出一个运算符,设为+,然后作运算a+b,并将运算结果压入操作数栈OVS。本次的运算符下次将重新考虑。
第二种方法——
首先对表达式进行线性化,然后将线性表达式转换成机器指令序列以便进行求值。
那么什么是表达式的线性化呢?人们所习惯的表达式的表达方法称为中缀表示。中缀表示的特点是运算符位于运算对象的中间。但这种表示方式,有时必须借助括号才能将运算顺序表达清楚,而且处理也比较复杂。
1929年,波兰逻辑学家Lukasiewicz提出一种不用括号的逻辑符号体系,后来人们称之为波兰表示法(Polish notation)。波兰表达式的特点是运算符位于运算对象的后面,因此称为后缀表示。在对波兰表达式进行运算,严格按照自左至右的顺序进行。下面给出一些表达式及其相应的波兰表达式。
表达式波兰表达式
A-B AB-
(A-B)*C+D AB-C*D+
A*(B+C/D)-E*F ABCD/+*EF*-
(B+C)/(A-D) BC+AD-/
OK,所谓表达式的线性化是指将中缀表达的表达式转化为波兰表达式。对于每一个表达式,利用栈可以把表达式变换成波兰表达式,也可以利用栈来计算波兰表达式的值
下面是代码
//西安科技大学-计算机科学与技术学院#include <iostream> #include <string> #include <cmath> using namespace std; const double PRECISION = 1E-6; const int COUNT_OF_NUMBER = 4; const int NUMBER_TO_BE_CAL = 24; double number[COUNT_OF_NUMBER]; string expression[COUNT_OF_NUMBER]; bool Judgement = false; //判断是否有解。int count = 0; void Search(int n) { if (n == 1) { if ( fabs(number[0] - NUMBER_TO_BE_CAL) <= PRECISION ) //对于除法,要小心小数的精确位数 { cout << expression[0] << "\t\t"; Judgement = true; count ++; if((count % 3)==0) cout<<endl; } else { } } for(int i=0; i < n; i++) { for (int j = i + 1; j < n; j++) { double a, b; string expa, expb; a = number[i]; b = number[j]; number[j] = number[n - 1]; //递归之后,n比以前小一位,所以可以不停向前赋值 expa = expression[i]; expb = expression[j]; expression[j] = expression[n - 1]; //递归之后,n比以前小一位,所以可以不停向前赋值 expression[i] = '(' + expa + '+' + expb + ')'; //加法不需要分顺序 number[i] = a + b; Search(n-1); expression[i] = '(' + expa + '-' + expb + ')'; //减法应该分顺序,减数以及被减数 number[i] = a - b; Search(n-1); expression[i] = '(' + expb + '-' + expa + ')'; //减法应该分顺序,减数以及被减数 number[i] = b - a; Search(n-1); expression[i] = '(' + expa + '*' + expb + ')'; //乘法不需要分顺序 number[i] = a * b; Search(n-1); if (b != 0) { expression[i] = '(' + expa + '/' + expb + ')'; //除法应该分顺序,除数以及被除数 number[i] = a / b; Search(n-1); } if (a != 0) { expression[i] = '(' + expb + '/' + expa + ')'; //除法应该分顺序,除数以及被除数 number[i] = b / a; Search(n-1); } number[i] = a; //这4句语句是为了防止如果上面几种可能都失败了的话, number[j] = b; //就把原来的赋值撤消回去,以无干扰的正确的进入到下一次 expression[i] = expa; //for循环队列中。 expression[j] = expb; // } }} int main() { cout<<"请依次输入4个数字:\n"; for (int i = 0; i < COUNT_OF_NUMBER; i++) { char buffer[20]; cout<<"第"<<i+1<<"个卡片:"; cin >> number[i]; itoa(number[i], buffer, 10); //itoa()函数的作用是把第一个参数(数值)传送到第二个参数(字符串)中去,第三个 //参数(int型)是该数值在字符串里以什么进制存放。 expression[i] = buffer; } cout<<endl; Search(COUNT_OF_NUMBER) ; if(Judgement==true) { cout << "\n成功" << endl; cout<<"所以可以计算的次数总和 = "<<count<<endl; } else { cout << "失败" << endl; } system("pause"); return 0;}
2 0
- 24点游戏 c语言的实现
- C语言实现24点游戏
- C语言实现简单24点游戏
- 24点游戏算法(C语言实现)
- 24点游戏的编程算法(C语言实现)
- 24 点游戏 c语言
- C语言:24点游戏
- C++实现24点游戏
- C++实现24点游戏
- 凑24点游戏实现
- Python实现24点游戏
- 24点游戏c语言源代码
- 24点游戏C语言源代码
- 24点游戏(C语言)
- C语言设计24点游戏。
- 24点纸牌游戏 c语言
- 【c#】24点游戏的实现(可存档且局域网互联)
- 经典游戏,计算24点,简单实现
- 加载properties文件 获取值
- java自定义泛型和反射泛型介绍
- HTML基本知识点——表单和表单元素标记
- NYOJ434_Jungle Roads(最小生成树)
- 模拟相机捕捉影像 将影像进行保存
- C++实现24点游戏
- C++的顶层const和底层const的理解
- Linux下find命令的解析
- vs和sqlserver连不上服务器的解决办法
- 4.11学习内容
- tensorflow 1.01中GAN(生成对抗网络)手写字体生成例子(MINST)的测试
- 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
- POJ 1330 Nearest Common Ancestors 【最近公共祖先】
- 零基础Linux下安装jdk与tomcat最精简版本