24点游戏输出表达式

带表达式输出的24点游戏,如果只是判断能不能组成24点,那么比较简单,输出所有的表达式不能将中间值保存到list中,需要额外的一个变量去保存中间结果,然后依次保存即可


package xwb.demo.leetcode;

/**
 * @Author 17912
 * @Date 2021-9-6-006 9:53:24
 * @Version 1.0
 */

import java.util.ArrayList;
import java.util.Random;

public class Main {

    public static void main(String[] args) {

        Random rd = new Random();
        Thinker ti = new Thinker();
        //随机生成10种数据求符合要求的表达式
        for (int j = 1; j < 11; j++) {
            ArrayList<Integer> card = new ArrayList<Integer>();
            System.out.println("第" + j + "组数据为:");
            int t;
            for (int i = 0; i < 4; i++) {
                t = rd.nextInt(13) + 1;
                card.add(t);
                System.out.print(t + " ");
            }
            System.out.println();
            ti.count(card, card.size() - 1, 24);
            System.out.println();
        }

    }
}

// 输出表达式类
class Expression {
    ArrayList<Integer> num = new ArrayList<Integer>();
    ArrayList<String> sign = new ArrayList<String>();

    // 重载add()方法对集合增加元素
    void add(int n) {
        num.add(n);
    }

    void add(String str) {
        sign.add(str);
    }

    // 获取运算符的优先级,“*与/”大于“+与-”
    int getPriority(String s) {
        if (sign.equals("+"))
            return 1;
        if (sign.equals("-"))
            return 1;
        if (sign.equals("*"))
            return 2;
        if (sign.equals("/"))
            return 2;
        return -1;
    }

    String toString(int la) {
        if (la == 0) {
            return num.get(0) + sign.get(0) + num.get(1);
        } else {
            String result = this.toString(la - 1);
            //若后面的运算符优先于前面的运算符,前面的表达式带上括号
            if (getPriority(sign.get(la)) >= getPriority(sign.get(la - 1)))
                result = "(" + result + ")";
            result += sign.get(la) + num.get(la + 1);
            return result;
        }
    }

    @Override
    public String toString() {
        return toString(2);
    }

    // 清除集合内的所有内容
    void clear() {
        num.clear();
        sign.clear();
    }
}

class Thinker {
    Expression exp = new Expression();

    boolean count(ArrayList<Integer> array, int index, int target) {
        //集合内为两个数时,穷举6种表达式
        if (index == 1) {
            if (array.get(0) + array.get(1) == target) {
                exp.add(array.get(0));
                exp.add(array.get(1));
                exp.add("+");
                return true;
            }

            if (array.get(0) - array.get(1) == target) {
                exp.add(array.get(0));
                exp.add(array.get(1));
                exp.add("-");
                return true;
            }

            if (array.get(1) - array.get(0) == target) {
                exp.add(array.get(1));
                exp.add(array.get(0));
                exp.add("-");
                return true;
            }

            if (array.get(0) * array.get(1) == target) {
                exp.add(array.get(1));
                exp.add(array.get(0));
                exp.add("*");
                return true;
            }

            if (array.get(0) * target == array.get(1)) {
                exp.add(array.get(0));
                exp.add(array.get(1));
                exp.add("/");
                return true;
            }

            if (array.get(1) * target == array.get(0)) {
                exp.add(array.get(1));
                exp.add(array.get(0));
                exp.add("/");
                return true;
            }

            return false;

        } else {
            for (int current = 0; current < array.size(); current++) {
                ArrayList<Integer> array1 = new ArrayList<Integer>();
                //currentNum为集合内当前读取的数字
                int currentNum = array.get(current);

                for (int i = 0; i < array.size(); i++) {
                    if (i != current) {
                        array1.add(array.get(i));
                    }
                }

                if (count(array1, index - 1, target - currentNum)) {
                    exp.add("+");
                    exp.add(currentNum);
                    if (index == 3) {
                        System.out.println(exp.toString());
                        exp.clear();

                    }
                    if (index != 3) {
                        return true;
                    }
                }
                if (count(array1, index - 1, target + currentNum)) {
                    exp.add("-");
                    exp.add(currentNum);
                    if (index == 3) {
                        System.out.println(exp.toString());
                        exp.clear();
                    }
                    if (index != 3) {
                        return true;
                    }
                }

                if (count(array1, index - 1, target * currentNum)) {
                    exp.add("/");
                    exp.add(currentNum);
                    if (index == 3) {
                        System.out.println(exp.toString());
                        exp.clear();
                    }
                    if (index != 3) {
                        return true;
                    }
                }

                if (target % currentNum == 0) {
                    if (count(array1, index - 1, target / currentNum)) {
                        exp.add("*");
                        exp.add(currentNum);
                        if (index == 3) {
                            System.out.println(exp.toString());
                            exp.clear();
                        }
                        if (index != 3) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }
}


不需要输出表达式的:采用回溯法,注意 + 和 * 有重复可以剪枝

 public boolean judgePoint24(int[] nums) {
        //    转成double
        List<Double> list = new ArrayList<>();
        for (int num : nums) {

            list.add((double) num);
        }
        return solve(list);
    }

    private boolean solve(List<Double> list) {
        if (list.size() == 0) {
            return false;
        }
        if (list.size() == 1) {
            return Math.abs(list.get(0) - 24.0) <= 0.01;
        }
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < list.size(); j++) {
                if (i == j) {
                    continue;
                }
                Double num1 = list.get(i);
                Double num2 = list.get(j);
                List<Double> nu = new ArrayList<>();
                for (int k1 = 0; k1 < list.size(); k1++) {
                    if (k1 == i || k1 == j) {
                        continue;
                    }
                    nu.add(list.get(k1));
                }
                
                for (int k = 0; k < 4; k++) {
                    if (k < 2 && j < i) {
                        continue;
                    }
                    double total;
                    // +
                    if (k == 0) {
                        total = num1 + num2;
                        //    *
                    } else if (k == 1) {
                        total = num1 * num2;

                        //    /
                    } else if (k == 2) {
                        //    -
                        total = num1 - num2;
                    } else {
                        if (num2 == 0) {
                            continue;
                        } else {
                            total = num1 / num2;
                        }

                    }

                    nu.add(total);
                    if (solve(nu)) {
                        return true;
                    }
                    nu.remove(nu.size() - 1);
                }

            }


        }
        return false;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值