查找和打印x1 + x2 + x3 = num的解决方案数量

时间:2019-05-31 16:20:08

标签: java recursion backtracking

我需要编写一个 recusive 函数,该函数可接收整数num并返回方程式:x1 + x2 + x3 = num的解数,其中x1,x2,x3是数字在1-10之间,该方法应打印所有解决方案。

例如,如果使用num=3,则该方法将打印1+1+1并返回1

如果num=5,该方法将返回6并打印:

1 + 1 + 3
1 + 2 + 2
1 + 3 + 1
2 + 1 + 2
2 + 2 + 1
3 + 1 + 1

如果num<3num>30,该方法将返回0

该方法应该是递归的而不使用循环。不允许使用全局变量。列表也不允许。

在这里,我的代码可以正常工作,但它也可以打印出重复的内容,其中num=5可以打印:

3 + 1 + 1
2 + 2 + 1
2 + 1 + 2
2 + 2 + 1
1 + 3 + 1
1 + 2 + 2
2 + 1 + 2
1 + 2 + 2
1 + 1 + 3

这是我的代码:

public static void main(String[] args) {
    System.out.println("num of solutions: "+solutions(5));

}

public static int solutions(int num) 
{

    if (num < 3 || num > 30)
        return 0;

    return solutions(num, 1, 1, 1);
}
private static int solutions(int num, int x1, int x2, int x3)
{
    if (x1 < 1 || x1 > 10 || x2 < 1 || x2 > 10||x3 < 1 || x3 > 10)
        return 0;
    if (x1 + x2 + x3 > num)
        return 0;       
    if (x1 + x2 + x3 == num)
    {
        System.out.println(x1 + " + " + x2 + " + " + x3);
        return 1;
    }           
    return solutions(num, x1 + 1, x2, x3) + solutions(num, x1, x2 + 1, x3) + solutions(num, x1, x2, x3 + 1);

}
  

如何获得没有重复的所需输出?

5 个答案:

答案 0 :(得分:2)

获取重复项的原因是solutions(1,2,1)solutions(2,1,1)都将引导您到2 + 2 + 1

不重复获取三位数的简单方法是将其从111计数到10,10,10,就好像是一个十进制整数一样:

private static int solutions(int num, int x1, int x2, int x3)
{
  if (x1 > 10 || x1 > num)
    return 0;
  if (x2 > 10 || x1+x2 > num)
    return solutions(num, x1+1, 1, 1);
  if (x3 > 10 || x1+x2+x3 > num)
    return solutions(num, x1, x2+1, 1);

  int me = 0;
  if (x1+x2+x3 == num) {
    System.out.printf("%d + %d + %d\n", x1, x2, x3);
    me=1;
  }
  return me + solutions(num, x1, x2, x3+1);
}

这模仿了您通过修剪来搜索整个空间的方法,但是更有效的解决方案可以只搜索x1x2并设置x3=num-x1-x2

答案 1 :(得分:0)

我们可以使用字符串解决此问题。声明一个全局字符串变量

static String str=""; // taken null intially

现在,我们可以使用此字符串str来存储序列,并检查它是否已经存在。这样,我们可以跟踪重复的副本,您将得到答案。我已附上我的代码,如下所示。

private static int solutions(int num, int x1, int x2, int x3)
{
    if (x1 < 1 || x1 > 10 || x2 < 1 || x2 > 10||x3 < 1 || x3 > 10)
        return 0;
    if (x1 + x2 + x3 > num)
        return 0;       
    if (x1 + x2 + x3 == num)
    {
        String s= String.valueOf(x1)+"+"+String.valueOf(x2)+"+"+String.valueOf(x2);
        if(!str.contains(s))
        {
            str=str+s+"\n";
            System.out.println(x1 + " + " + x2 + " + " + x3);
            return 1;
        }
    }           
    return solutions(num, x1 + 1, x2, x3) + solutions(num, x1, x2 + 1, x3) + solutions(num, x1, x2, x3 + 1);

}

答案 2 :(得分:0)

嗯...没有集合,没有全局变量,没有重复项。我希望您被允许使用StringBuilder?

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder();

    System.out.println("num of solutions: " + solutions(5, sb));

    System.out.println(sb.toString());
}

public static int solutions(int num, StringBuilder sb) {
    if (num < 3 || num > 30)
        return 0;

    return solutions(num, 1, 1, 1, sb);
}

private static int solutions(int num, int x1, int x2, int x3, StringBuilder sb) {
    if (x1 > 10 || x2 > 10 || x3 > 10) {
        return 0;
    }

    if (x1 + x2 + x3 > num) {
        return 0;
    }

    if (x1 + x2 + x3 == num) {
        String str = x1 + " + " + x2 + " + " + x3;
        if (!sb.toString().contains(str)) {
            sb.append(str).append(System.lineSeparator());
            return 1;
        }
    }

    return solutions(num, x1 + 1, x2, x3, sb) 
           + solutions(num, x1, x2 + 1, x3, sb) 
           + solutions(num, x1, x2, x3 + 1, sb);
}

结果:

    num of solutions: 6
    3 + 1 + 1
    2 + 2 + 1
    2 + 1 + 2
    1 + 3 + 1
    1 + 2 + 2
    1 + 1 + 3

答案 3 :(得分:0)

尝试一下:

public static void main(String... args) {
    System.out.println(solutions(5));
}
public static int solutions(int n) {

    if (n < 3 || n > 30) return 0;
    return solutions(n, n-2, 1, 1, 0);

}

public static int solutions(int n, int x1, int x2, int x3, int solutions) {

    ++solutions;
    System.out.println("Solution found : "+x1 +"+" + x2 + "+" + x3);

    if(x3 == n-2) return solutions;

    if(x2 > 1) {
        return solutions(n, x1, x2-1, x3+1, solutions);
    }

    if(x1 > 1) {
        return solutions(n, x1-1, n-x1, 1, solutions);
    }
    return solutions;
}

输出:6

想法如下:

您最好从x1开始。

然后您遵循以下两个规则:

如果x2> 1然后x2 = x2-1和x3 = x3 + 1

如果不是,并且x1> 1则x1 = x1-1,x3 = 1和x2 =拥有正确总数的数字。

如果这两个条件都不成立,就没有其他解决方案。

结果:

3 +1 +1

第一个条件为假,第二个条件为真: 我们将1删除到x1,x3变成1,x2逻辑上变成2

2 + 2 +1

第一个条件为真。 我们将1删除到x2,然后将1添加到x3

2 +1 + 2

第一个条件为假

第二个条件为

1 + 3 +1

第一个条件为

1 + 2 + 2

第一个条件为

1 +1 + 3

第一个条件为假,第二个条件为假。

我们有6个解决方案,就可以了。

希望有帮助!

答案 4 :(得分:-2)

您可以跟踪所有已打印的字符串,并且仅在该字符串不是已打印的字符串之一时才打印