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,這種數字計算出來的結果會有很多,但實際上沒有那麼多。

時間有限,不能去考慮細節了。

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