计算24点算法基本原理是穷举4个整数所有可能的表达式,然后对表达式求值。表达式的定义: expression = (expression|number) operator (expression|number)
因为能使用的4种运算符 + - * / 都是2元运算符,所以本文中只考虑2元运算符。2元运算符接收两个参数,输出计算结果,输出的结果参与后续的计算。由上所述,构造所有可能的表达式的算法如下:
(1) 将4个整数放入数组中
(2) 在数组中取两个数字的排列,共有 P(4,2) 种排列。对每一个排列,
 (2.1) 对 + - * / 每一个运算符,
  (2.1.1) 根据此排列的两个数字和运算符,计算结果
  (2.1.2) 改表数组:将此排列的两个数字从数组中去除掉,将 2.1.1 计算的结果放入数组中
  (2.1.3) 对新的数组,重复步骤 2
  (2.1.4) 恢复数组:将此排列的两个数字加入数组中,将 2.1.1 计算的结果从数组中去除掉可见这是一个递归过程。步骤 2 就是递归函数。当数组中只剩下一个数字的时候,这就是表达式的最终结果,此时递归结束。在程序中,一定要注意递归的现场保护和恢复,也就是递归调用之前与之后,现场状态应该保持一致。在上述算法中,递归现场就是指数组,2.1.2 改变数组以进行下一层递归调用,2.1.3 则恢复数组,以确保当前递归调用获得下一个正确的排列。括号 () 的作用只是改变运算符的优先级,也就是运算符的计算顺序。所以在以上算法中,无需考虑括号。括号只是在输出时需加以考虑。对象设计如下:
类 类含有的变量 类含有的方法 说明Number double value String toString() 这样可以清晰地表达出 expression 的递归定义Expression extends Number Number left Number right char operator String toString() Calculator Number[] numbers Expression[] expressions
               add() clear() //操作 numbers
               calculate()
               Permutor permutor() java 程序的主类,实现算法Permutor int i,j        boolean next() 排列生成器,类似 iterator,从一个指定的数组中生成2个元素的排列

解决方案 »

  1.   


    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Random;
    class Detail {
        int value;
        String strValue;    public Detail() {
        }    public Detail(int value) {
            this.value = value;
            this.strValue = String.valueOf(value);
        }
    }
    public class C24 {
        /**
         * @param args
         */
        public static void main(String[] args) {
            C24 c24 = new C24();        c24.C24p();
        }    void C24p() {
            int[] srcCards = generateCards();
            boolean hasAnswer = false;        // int[] srcCards ={4,1,2,10};
            try {
                List<int[]> all = allPermutation(srcCards);
                List<Detail> results = new ArrayList<Detail>();            for (int[] cards : all) {
                    List<Detail> oneCase = calEachCase(cards);
                    results.addAll(oneCase);
                }            for (Detail detail : results) {
                    if (detail.value == 24) {
                        hasAnswer = true;
                        System.out.println(detail.strValue);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println(Arrays.toString(srcCards));
            }        if (!hasAnswer) {
                System.out.println("No Answer");
                System.out.println(Arrays.toString(srcCards));
            }
        }    int[] generateCards() {
            int[] rtn = new int[4];
            Random rand = new Random();        for (int i = 0; i < rtn.length; i++) {
                rtn[i] = rand.nextInt(10) + 1;
            }        return rtn;
        }    List<int[]> allPermutation(int[] cards) {
            List<int[]> rtn = new ArrayList<int[]>();
            int length = cards.length;        if (length == 1) {
                rtn.add(cards);            return rtn;
            }        for (int i = 0; i < length; i++) {
                int card = cards[i];
                int[] leftCards = removeOne(cards, i);
                List<int[]> newRtn = allPermutation(leftCards);            for (int[] js : newRtn) {
                    int[] newCards = new int[length];
                    newCards[0] = card;
                    System.arraycopy(js, 0, newCards, 1, length - 1);
                    rtn.add(newCards);
                }
            }        return rtn;
        }    int[] removeOne(int[] cards, int index) {
            int[] newCards = new int[cards.length - 1];
            int j = 0;        for (int i = 0; i < cards.length; i++) {
                if (index != i) {
                    newCards[j] = cards[i];
                    j++;
                }
            }        return newCards;
        }    List<Detail> calEachCase(int[] cards) {
            List<Detail> list = new ArrayList<Detail>();
            int x = cards[0];
            int y = cards[1];
            int z = cards[2];
            int u = cards[3];
            List<Detail> listA = cal(new Detail(x), new Detail(y));
            List<Detail> listB = cal(new Detail(z), new Detail(u));
            list.addAll(cal(listA, listB));        List<Detail> list1 = cal(new Detail(x), new Detail(y));
            List<Detail> list2 = cal(list1, new Detail(z));
            List<Detail> list3 = cal(list2, new Detail(u));
            list.addAll(list3);        return list;
        }    List<Detail> cal(Detail detail1, Detail detail2) {
            int x = detail1.value;
            int y = detail2.value;
            String strX = detail1.strValue;
            String strY = detail2.strValue;
            List<Detail> rtnList = new ArrayList<Detail>();
            Detail detail = null;
            detail = new Detail();
            detail.value = x + y;
            detail.strValue = "(" + strX + "+" + strY + ")";
            rtnList.add(detail);
            detail = new Detail();
            detail.value = x - y;
            detail.strValue = "(" + strX + "-" + strY + ")";
            rtnList.add(detail);
            detail = new Detail();
            detail.value = x * y;
            detail.strValue = "(" + strX + "*" + strY + ")";
            rtnList.add(detail);        if ((y != 0) && ((x % y) == 0)) {
                detail = new Detail();
                detail.value = x / y;
                detail.strValue = "(" + strX + "/" + strY + ")";
                rtnList.add(detail);
            }        return rtnList;
        }    List<Detail> cal(List<Detail> list, Detail detail) {
            List<Detail> rtnList = new ArrayList<Detail>();        for (Detail det : list) {
                rtnList.addAll(cal(det, detail));
            }        return rtnList;
        }    List<Detail> cal(List<Detail> list1, List<Detail> list2) {
            List<Detail> rtnList = new ArrayList<Detail>();        for (Detail detail1 : list1) {
                for (Detail detail2 : list2) {
                    rtnList.addAll(cal(detail1, detail2));
                }
            }        return rtnList;
        }
    }引用别人的,可以参考下。