public class TestPossibleNumbers {
public static void main(String[] args) {
int input[] = { 1, 2, 3 };
// int input[] = {10,11,12,13};
possibleNumbers(input, 0);
}
public static void possibleNumbers(int[] x, int index) {
if (index == x.length) {
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + " ");
}
System.out.println();
}
for (int i = index; i < x.length; i++) {
int temp = x[index];
x[index] = x[i];
x[i] = temp;
possibleNumbers(x, index + 1);
temp = x[index];
x[index] = x[i];
x[i] = temp;
}
}}
任何人都可以帮我理解for循环中的代码吗? 这个程序运行得很好。但是,我无法弄清楚它是如何工作的
答案 0 :(得分:1)
您将在以下位置递归调用该方法:
possibleNumbers(x, index + 1);
因此,该方法再次运行该方法,并传递了索引+ 1。它检查是否
if(index == x.length)
如果陈述正确,则打印数字。
然后再次进入第二个for循环(如果if语句不正确,它仍然会输入它)。并再次调用重复方法。它将继续输入2nd for循环,但是当“index”等于或大于“i.length”时,for循环的迭代不会运行,因为你指定for循环仅在以下时间运行:
i<i.length
当2 for循环不进行任何迭代时,该方法将停止重复出现。所以在你的情况下,当index等于3时,不会运行第二个for循环的迭代。
尝试逐步运行调试,以更深入地了解正在发生的事情。
答案 1 :(得分:0)
我会提供另一种解释,我觉得更直观。
考虑列表中只有1个数字的情况:[a]。这非常简单:只有一个组合[a]。
现在考虑列表中2个数字的情况:[a,b]。在这种情况下,您可以依次获取每个元素,然后使用前一个方法查看剩余元素的所有组合,然后再添加元素。
现在考虑列表中3个数字的情况:[a,b,c]。在这种情况下,您可以依次获取每个元素,然后使用前一个方法查看其他2个元素的所有组合,然后再添加元素。
等等3,4,5 ......元素。
因此,一般来说,请考虑列表中n个数字的情况:[a1,a2,... an]。在这种情况下,依次取出每个元素,然后使用完全相同的方法查看其他n-1个元素的所有组合,然后再添加元素。
转换为伪代码:
getCombos(values)
for each value
for each combo in getCombos(values with value removed)
add value + combo to results
return results
唯一要添加的是基本案例,这是所有递归实现所必需的。一种可能性是单个项目的情况。然而,更简单的一个:如果没有值,那么结果就是一个空列表。
因此将其转换为Java,使用集合清楚地表明元素必须是唯一的(以避免重复的结果),使用流并使其成为通用的,以便它适用于任何类型:
Stream<List<C>> combos(Set<C> values) {
if (values.isEmpty())
return Stream.of(new ArrayList<>());
else
return values.stream().flatMap(value ->
combos(values.stream()
.filter(v -> !v.equals(value))
.collect(toSet())).peek(r -> r.add(value)));
}
您的代码实际上只是同一算法的替代实现,它将所考虑的元素交换到数组的前端,而不是创建新的集合。
答案 2 :(得分:0)
程序打印数字的排列而不是组合。
排列 - 订单很重要 组合 - 顺序无关紧要,更多的是从n
中选择k个元素例如
int a= {a,b};
permutation = {ab,ba}
whereas combination ={{},{a},{b},{a,b}}
了解该计划的运作方式 通过以下链接将 https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
不要对for循环中的递归感到困惑。
if (index == x.length)
是递归的终止条件。
在调用递归调用possibleNumbers
之前和之后的for循环中,交换了元素。
在交换之前有助于生成所有可能的结果,并且交换元素将交换到先前的位置,以便从for循环生成所有其他排列。这可能听起来令人困惑,请通过链接。