问题
I need to write a recusive function that recive an integer num
and returns the number of solutions to the equation :x1 + x2 + x3 = num
, where x1,x2,x3
are numbers between 1-10, the method should print all solutions.
For example if num=3
then the method will print 1+1+1
and will return 1
.
if num=5
the method will return 6
and will print:
1 + 1 + 3
1 + 2 + 2
1 + 3 + 1
2 + 1 + 2
2 + 2 + 1
3 + 1 + 1
if num<3
or num>30
the method will return 0
.
The method should be recursive without using loops. Global variables are not allowed. Lists are also not allowed.
Here my code, it works fine but it also prints duplicates, for num=5
it prints:
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
Here is my code:
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);
}
How do I get the desired output without duplicates?
回答1:
The reason why you're getting duplicates is that both solutions(1,2,1)
and solutions(2,1,1)
will lead you to 2 + 2 + 1
.
The trivial way of not getting duplicate for three digits is count up from 111 to 10,10,10 as if it was a decimal integer:
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);
}
This mimics your approach of searching through the full space with pruning, but a more efficient solution could just search through x1
and x2
and set x3=num-x1-x2
.
回答2:
We can solve this problem using string. Declare one global string variable
static String str=""; // taken null intially
Now, we can use this string str to store the sequence and to check whether it already comes before or not. This way we can keep track of the duplicate one and you will get your answer. I have attached my code as below.
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);
}
回答3:
Well... no collections, no global variables, no duplicates. I hope you are allowed to use 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);
}
Result:
num of solutions: 6
3 + 1 + 1
2 + 2 + 1
2 + 1 + 2
1 + 3 + 1
1 + 2 + 2
1 + 1 + 3
回答4:
Try this :
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;
}
Output : 6
The idea is the following :
You start with x1 the greatest as possible.
Then you follow these two rules :
if x2 > 1 THEN x2 = x2 - 1 and x3 = x3 + 1
if not, and if x1 > 1 THEN x1 = x1 - 1, x3 = 1 and x2 = the number required to have the correct total.
If none of these two conditions are true, there is no more solutions.
Result :
3 + 1 + 1
First condition false, second true : We remove 1 to x1, x3 becomes 1 and x2 becomes logically 2
2 + 2 + 1
First condition is true. We remove 1 to x2 and add 1 to x3
2 + 1 + 2
First condition is false
Second condition is true
1 + 3 + 1
First condition is true
1 + 2 + 2
First condition is true
1 + 1 + 3
First condition is false, second is false.
We have our 6 solutions, so there it is.
Hope that helped !
来源:https://stackoverflow.com/questions/56398612/find-and-print-num-of-solutions-to-x1x2x3-num