首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何找到一个公式的所有可能的解决方案,如100*7-8*3+7?(每10只猫中有8只是倒数求解者)

如何找到一个公式的所有可能的解决方案,如100*7-8*3+7?(每10只猫中有8只是倒数求解者)
EN

Stack Overflow用户
提问于 2015-07-23 20:56:33
回答 1查看 1.7K关注 0票数 10

因此,作为乐趣,我决定编写一个简单的程序,可以解决8/ 10猫做倒计时数谜,链接是形式倒计时,但同样的规则。因此,我的程序简单地通过了所有可能的AxBxCxDxExF组合,其中字母是数字,"x“是+,-,和*。这是它的代码:

代码语言:javascript
复制
private void combineRecursive( int step, int[] numbers, int[] operations, int combination[]){
    if( step%2==0){//even steps are numbers
        for( int i=0; i<numbers.length; i++){
            combination[ step] = numbers[ i];
            if(step==10){//last step, all 6 numbers and 5 operations are placed
                int index = Solution.isSolutionCorrect( combination, targetSolution);
                if( index>=0){
                    solutionQueue.addLast( new Solution( combination, index));
                }
                return;
            }
            combineRecursive( step+1, removeIndex( i, numbers), operations, combination);
        }
    }else{//odd steps are operations
        for( int i=0; i<operations.length; i++){
            combination[ step] = operations[ i];
            combineRecursive( step+1, numbers, operations, combination);
        }
    }
}

这是我用来测试的,如果组合是我不想做的。

代码语言:javascript
复制
public static int isSolutionCorrect( int[] combination, int targetSolution){
    double result = combination[0];
    //just a test
    if( Arrays.equals( combination, new int[]{100,'*',7,'-',8,'*',3,'+',7,'+',50})){
        System.out.println( "found");
    }
    for( int i=1; i<combination.length; i++){
        if(i%2!=0){
            switch( (char)combination[i]){
                case '+': result+= combination[++i];break;
                case '-': result-= combination[++i];break;
                case '*': result*= combination[++i];break;
                case '/': result/= combination[++i];break;
            }
        }
        if( targetSolution==result){
            return i;
        }
    }       
    return targetSolution==result?0:-1;
}

所以在上一集我发现我的代码出了问题。这是其中一个谜题的解决方案。

代码语言:javascript
复制
(10*7)-(8*(3+7))

我注意到我确实找到了这个组合"10*7-8*3+7“(两次),但是因为我通过从左到右的操作来检查解决方案,我实际上找不到所有的答案。我只检查这样的解决方案(10*7)-8)*3)+7)。所以,即使我找到了密码,我也没有正确的顺序。

那么现在的问题是如何测试所有可能的数学顺序,比如(10*7)-(8*(3+7)),(10*7)-((8*3)+7)或10*(7-8)*(3+7)?我想我可以使用一个平衡树与操作作为平衡节点。但我仍然不知道如何通过所有可能的组合,而不移动公式。

代码语言:javascript
复制
(10*7)-(8*(3+7))
          -
     /        \
    *         *
  /   \      /  \
700   7     8    +
                / \
              7    3

(10*7)-((8*3)+7)
          -
     /        \
    *         +
  /   \      /  \
700   7     *    7
           / \
          8  3

10*(7-8)*(3+7)

                 *
           /           \
          *
     /        \         10
    -          +
  /   \      /  \
7     8     3    7

我怎么用代码来完成这个任务呢?不寻找已解决的代码,更多的是我应该如何改变视角来修复它。我不知道为什么我对此感到困惑。

关于我:第四年计算机科学,不是新的或编程新手(我至少喜欢相信;)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-23 22:38:39

使用表示表达式的专用类(而不是数组)更容易解决这一问题。然后,您可以简单地枚举所有可能的树。我为类似的任务写的另一个答案显示如何生成所有二叉树的答案。的混合给出了这样的结果:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class NumberPuzzleWithCats
{
    public static void main(String[] args)
    {
        List<Integer> numbers = Arrays.asList(10,7,8,3,7);
        solve(numbers);
    }

    private static void solve(List<Integer> numbers)
    {
        List<Node> nodes = new ArrayList<Node>();
        for (int i=0; i<numbers.size(); i++)
        {
            Integer number = numbers.get(i);
            nodes.add(new Node(number));
        }
        System.out.println(nodes);
        List<Node> all = create(nodes);
        System.out.println("Found "+all.size()+" combinations");


        for (Node node : all)
        {
            String s = node.toString();
            System.out.print(s);
            if (s.equals("((10*7)-(8*(3+7)))"))
            {
                System.out.println(" <--- There is is :)");
            }
            else
            {
                System.out.println();
            }
        }
    }

    private static List<Node> create(Node n0, Node n1)
    {
        List<Node> nodes = new ArrayList<Node>();
        nodes.add(new Node(n0, '+', n1));
        nodes.add(new Node(n0, '*', n1));
        nodes.add(new Node(n0, '-', n1));
        nodes.add(new Node(n0, '/', n1));
        nodes.add(new Node(n1, '+', n0));
        nodes.add(new Node(n1, '*', n0));
        nodes.add(new Node(n1, '-', n0));
        nodes.add(new Node(n1, '/', n0));
        return nodes;
    }

    private static List<Node> create(List<Node> nodes)
    {
        if (nodes.size() == 1)
        {
            return nodes;
        }
        if (nodes.size() == 2)
        {
            Node n0 = nodes.get(0);
            Node n1 = nodes.get(1);
            return create(n0, n1);
        }
        List<Node> nextNodes = new ArrayList<Node>();
        for (int i=1; i<nodes.size()-1; i++)
        {
            List<Node> s0 = create(nodes.subList(0, i));
            List<Node> s1 = create(nodes.subList(i, nodes.size()));
            for (Node n0 : s0)
            {
                for (Node n1 : s1)
                {
                    nextNodes.addAll(create(n0, n1));
                }
            }
        }
        return nextNodes;
    }

    static class Node
    {
        int value;
        Node left;
        Character op;
        Node right;

        Node(Node left, Character op, Node right)
        {
            this.left = left;
            this.op = op;
            this.right = right;
        }
        Node(Integer value)
        {
            this.value = value;
        }

        @Override
        public String toString()
        {
            if (op == null)
            {
                return String.valueOf(value);
            }
            return "("+left.toString()+op+right.toString()+")";
        }
    }
}

它将打印创建的所有组合,包括您一直在寻找的组合:

代码语言:javascript
复制
[10, 7, 8, 3, 7]
Found 16384 combinations
(10+(7+(8+(3+7))))
(10*(7+(8+(3+7))))
...
((10*7)+(8*(3+7)))
((10*7)*(8*(3+7)))
((10*7)-(8*(3+7))) <--- There is is :)
((10*7)/(8*(3+7)))
((8*(3+7))+(10*7))
...
((7/3)-((8/7)/10))
((7/3)/((8/7)/10))

当然,通过比较String表示来检查是否找到了正确的解决方案。“非常务实”,可以这么说,但我认为这一代人的实际做法才是最重要的。

(我希望这是你一直在寻找的东西-我不能查看你链接到的网站.)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31597886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档