24点计算器算法

这是一个经典问题,具体问题:从1-13的整数里,选择四个数字,允许重复,并运用+,-,*,/,()对这四个数字进行运算,如果答案等于24,则输出“yes”,否则输出“no”。

最开始以为能找到规律,但是想了很久,实在无果,查资料发现好像确实没有成熟的算法。就直接暴力算法,因为其实复杂度并不高,没有多少优化的必要性。顶多加上一些判断,减少循环的次数。

一篇与该文有关的博文:http://blog.csdn.net/lsjweiyi/article/details/68495556(4个数的排列组合)

我写了一个Java的程序:

import java.util.Scanner;
public class Main {
    static int times=0;
    public static void main(String[] args) {
        System.out.println("请输入数字:");
        //从控制台获取数字
        Scanner sc=new Scanner(System.in);
        int[] array=new int[4]; 
        for(int i=0;i<4;i++)
            array[i]=sc.nextInt();

        System.out.println("结果:");
        combination(array);
        System.out.println(times);//输出共有多少种组合
    }

    static int twoInt(int a,int b,int i) throws ArithmeticException{//两个数字与4中运算符的组合,5种
        if(i==0)
            return a+b;
        else if(i==1)
            return a-b;
        else if(i==2)
            return a*b;
        else 
            return a/b;

    }
    static void fourInt(int a,int b,int c,int d){
        int s1 = 0;
        int s2 = 0;
        int s3 = 0;
        //共三层循环,第一层是a,b,第二层是(a,b),c,第三层是((a,b),c),d
        for(int i=0;i<4;i++){
            try {
                s1=twoInt(a, b, i);
            } catch (Exception e) {
                continue;
            }
            for(int j=0;j<4;j++){
                try {
                    s2=twoInt(c,s1,j);
                } catch (Exception e) {
                    continue;
                }
                for(int k=0;k<4;k++){
                    try {
                        s3=twoInt(d,s2,k);
                    } catch (Exception e) {
                        continue;
                    }
                    if(s3==24){
                        System.out.print("yes"+" ");
                        times++;
                    }
                }
            }
        }
    }

    //对四个数进行排列组合,前面提供的链接里有详细介绍
    static void combination(int array[]) {
        if(array.length!=4){
            System.out.println("数组长度不为4");
            System.exit(0);
        }
        for(int i=0;i<4;i++){
            System.out.println();
            for(int j=0;j<4;j++){
                if(j==i)
                    continue;
                for(int k=0;k<4;k++){
                    if(k==j||k==i)
                        continue;
                    for(int h=0;h<4;h++){
                        if(h==k||h==j||h==i)
                            continue;
                        fourInt(array[i], array[j], array[k], array[h]);

                    }
                }
            }
        }
    }
}

思路:
1、static int twoInt(int a,int b,int i),这个方法就是两个数字与4个运算符的组合,返回组合的结果,a,b为两个整数,i的作用是判断输出哪种组合。

2、static void fourInt(int a,int b,int c,int d),这个方法是返回这四个数按顺序用四种不同的运算符组成的式子的结果,先(a?b)与四个运算符组成,有4种可能,再与c组合:(a?b)?c,再与d组合((a?b)?c)?d
(?代表某种运算符)。

3、static void combination(int array[]),这个方法是返回数组里4个数字的各种组合,共24种,因为第二个方法里,只是对a,b,c,d这一种顺序进行遍历,而b,a,c,d这种组合得出的结果是不一样的,所以要对每一种情况进行遍历。这样,就把所有的可能都遍历完了。

这段代码能保证的是只要存在符合题意的组合能找出来,但不找出所有组合,以及无法区别有重复数字的情况,例如2, 2,2,3,这种数字计算出来的结果会有很多,但实际上没有那么多。

时间有限,不能去考虑细节了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章