基于递归全排算法的最笨方式实现24点游戏

来源:互联网 发布:网络小周迅BT 编辑:程序博客网 时间:2024/06/07 18:31

能够想到这个题目我自己也是醉了,写论文写傻了的结果么。。

目标只有一个:给定任意四个整数,求解出所有可能的经过基本算术(+ - * %)之后得到24点的组合。即通过编程实现24点。下面是我的想法:首先,通过全排方法找到所有的排列组合,然后在任意一组组合数中间插入3个算术符号,比如,给定四个整数是(5,6,8,9),那么假设其中一组全排结果是(5,9,6,8),用数组num表示,如下图:


那么在每两个整数中间可以插入任意四个算术符号中的一个,一共是3个符号,设为字符数组sign1。我通过3次for循环得到所有的sign1可能结果。于是,在每得到的一组全排结果中,我就可以将sign1运用到其中,检测经过顺序运算之后的结果是否为24(注意是顺序运算,即第一个数先和第二个数计算,所得结果再与第三个数计算,最后再与第四个数计算,忽略先乘除后加减的规则,因为全排已经将所有情况包括在内)

这没有涉及到更多的算法设计知识,只是我能够第一个想到的实现方法,也可以称之为最笨实现方式(因为这里需要多次循环嵌套,耗时间)。具体实现如下:

/** *  */package collections;/** * @author Shaw * */public class CollTest24 {/**功能:main函数 * @param args */public static void main(String[] args) {// TODO int[] num = new int[]{9,8,5,6};perm(num, 0, num.length-1);}/** * 功能:使用递归方法数组全排, * @param num * @param start * @param end */private static void perm(int[] num, int start, int end) {// TODOif (start == end) {//打印输出整个数组,这是其中一种组合/*System.out.print("[");for (int i = 0; i < num.length; i++) {if (i==num.length-1) {System.out.println(num[i]+"]");} else System.out.print(num[i]+" ");}*///在这个基础上尝试是否可以得到24点try24(num);} else {for (int i = start; i < num.length; i++) {swap(num, start, i);perm(num, start+1, end);swap(num, start, i); }}}/** * 功能:交换数组中的元素 * @param num 数组 * @param start 数组下标 * @param i 数组下标 */public static void swap(int[] num, int start, int i) {int temp = num[i];num[i] = num[start];num[start] = temp;}/** * 功能:组合计算24点 * 最笨的方法:将四个数之间的三个可能的符号全部罗列出来,进行计算 * @param num */private static void try24(int[] num) {// TODOchar[] sign = new char[]{'+','-','*','%'};char[] sign1 = new char[3];//四个数之间的三个可能的符号for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++){for (int k = 0; k < 4; k++){sign1[0]= sign[i];sign1[1]= sign[j];sign1[2]= sign[k];calculation(sign1,num);}}}}/** * 功能:具体计算过程 * @param sign1 3个符号组成的数组 * @param num   四个数全排得到的其中一个结果组成的数组 */private static void calculation(char[] sign1, int[] num) {// TODO double result = 0;switch(sign1[0]){case '+':{result = num[0]+num[1];break;}case '-':{result = num[0]-num[1];break;}case '*':{result = num[0]*num[1];break;}case '%':{result = num[0]%num[1];break;}}switch(sign1[1]){case '+':{result = result+num[2];break;}case '-':{result = result-num[2];break;}case '*':{result = result*num[2];break;}case '%':{result = result%num[2];break;}}switch(sign1[2]){case '+':{result = result+num[3];break;}case '-':{result = result-num[3];break;}case '*':{result = result*num[3];break;}case '%':{result = result%num[3];break;}}//输出符合要求的结果if(result == 24.0) System.out.println("(("+num[0]+sign1[0]+num[1]+')'+sign1[1]+num[2]+')'+sign1[2]+num[3]+"=24");}}


输出结果:

((9-5)%8)*6=24((9%5)%8)*6=24((9*5)%6)*8=24((9-6)%5)*8=24((9%6)%5)*8=24((8-9)+5)*6=24((8+5)-9)*6=24((8+5)%9)*6=24((8*5)%9)*6=24((5+8)-9)*6=24((5+8)%9)*6=24((5*8)%9)*6=24((5-9)+8)*6=24((5*9)%6)*8=24((5*6)%9)*8=24((6*5)%9)*8=24


更加高效的方法还没有学会,因为脑子不够用额。。。接下来尝试看看如何用数据结构的优越性来实现这个问题。

同样的,需要考虑的问题还有:1*2*3*4=24 与2*3*1*4=24其实同一个解,如何可以不重复?接下来再尝试吧

0 0
原创粉丝点击