如何解决有人可以解释这个代码,该代码生成给定集合的所有可能置换吗?
我在
竞争性程序员手册也可以做到这一点,但我正努力理解其背后的逻辑。
它指出:
像子集一样,可以使用递归来生成排列。以下 函数搜索遍历集合{0,1,...,n¡1}的排列。的 函数构建包含该置换的向量置换,并且 当调用不带参数的函数时,搜索开始。
void search() {
if (permutation.size() == n) {
// process permutation
} else {
for (int i = 0; i < n; i++) {
if (chosen[i]) continue;
chosen[i] = true;
permutation.push_back(i);
search();
chosen[i] = false;
permutation.pop_back();
}
}
}
每个函数调用都会向置换添加一个新元素。选择的数组 指示排列中已包含哪些元素。如果大小 排列等于集合的大小,已生成排列。
我似乎无法理解正确的直觉和所使用的概念。
有人可以向我解释代码在做什么以及其背后的逻辑是什么吗?
解决方法
您可以像这样拆分代码:
void search() {
if (permutation.size() == n) {
// we have a valid permutation here
// process permutation
} else {
// The permutation is 'under construction'.
// The first k elements are fixed,// n - k are still missing.
// So we must choose the next number:
for (int i = 0; i < n; i++) {
// some of them are already chosen earlier
if (chosen[i]) continue;
// if i is still free:
// signal to nested calls that i is occupied
chosen[i] = true;
// add it to the permutation
permutation.push_back(i);
// At the start of this nested call,// the permutation will have the first (k + 1)
// numbers fixed.
search();
// Now we UNDO what we did before the recursive call
// and the permutation state becomes the same as when
// we entered this call.
// This allows us to proceed to the next iteration
// of the for loop.
chosen[i] = false;
permutation.pop_back();
}
}
}
直觉可能是search()
是“以所有可能的方式完成当前部分构造的置换并处理所有置换”。
如果它已经完成,我们只需要处理一个可能的排列。 如果没有,我们可以首先以各种可能的方式选择第一个数字 ,然后针对每种方式,递归地完成排列。
,我会尝试给你一些直觉。主要思想是 回溯 。您基本上会构建一个解决方案,直到遇到死胡同。当您遇到死胡同时,请回到最后一个位置,在这里您可以执行与上次不同的操作。让我来看一下我为region
绘制的模拟。
首先,你什么都没有。先走n = 3
,然后走1
再走2
。您现在无处可去,即 Dead End 。您将打印当前的3
排列,您现在要做什么?回到123
,因为您知道这次可以走1
可以走另一条路。那么,您这次以同样的方式得到什么? 3
。 使用1还能执行其他操作吗? 否 。现在回到一无所有,重新开始同样的事情,现在使用132
。您现在明白了吧?
对于代码中发生的相同情况:
2
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。