Algorithm N选择K的迭代算法,无重复,顺序重要
我正在寻找一种迭代算法,以获得从一组N个元素中提取的K个元素的所有排列,无需重复(即,无替换),并且顺序很重要。 我知道排列的数量必须是N/(N-K)!。 你有什么想法吗? 多谢各位Algorithm N选择K的迭代算法,无重复,顺序重要,algorithm,iteration,permutation,Algorithm,Iteration,Permutation,我正在寻找一种迭代算法,以获得从一组N个元素中提取的K个元素的所有排列,无需重复(即,无替换),并且顺序很重要。 我知道排列的数量必须是N/(N-K)!。 你有什么想法吗? 多谢各位 Ivan方法1: [0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]. [0,1,2] // initialization [0,2,1] // next permutation ... // all perm
Ivan方法1:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
更简单的想法:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
由于顺序很重要,我们将尝试使用下一个排列
。next\u permutation
函数提供了next字典中唯一的排列
算法:
next\u permutation
迭代置换时,只选择原始数组中值为>0的索引,保持顺序[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
因为在新创建的数组中有N个重复的N-k个数,所以总的唯一排列变为N/(N-k)!这给了我们想要的结果
示例:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
输入:X=[1,2,3],k=2
现在,我们创建一个=[0,1,2]
所有排列:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
仅从原始数组中选择这些置换的索引i,其中[i]>0将产生
[2,3],
[3,2],
[1,3],
[1,2],
[3,1],
[2,1].
如果您希望按排序顺序执行上述操作,请使用负数,并使用-k、-k-1、…-1初始化前k个数字,剩余的数字为0,并通过在原始数组中选择索引i来应用算法,以便在保持顺序的同时[i]<0
旁注:
如果顺序不重要,则在开始处用k
-1s初始化A
,剩余的0,并使用迭代排列算法,该算法将从N个项目中生成唯一的可能k个选择
方法2:(优于方法1)
算法:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
A
,它将存储原始数组中所选元素的索引。我们把它列为第一选择[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
我们考虑当前的组合,找出最右边的元素。
这还没有达到可能的最高值。一旦找到这个
元素,我们将其递增1,并为
所有后续元素
发件人:
示例:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
输入:X=[1,2,3,4],k=3
现在,我们创建一个=[0,1,2]
所有排列:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
代码(基于0的索引,因此从0-k-1初始化开始):
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
bool-next\u-composition\u与顺序(向量&a,int-n,bool-order\u-matters=true){
int k=(int)a.size();
if(order_matters&&std::next_排列(a.begin(),a.end())返回True;//检查下一个排列是否存在,否则向前移动并获得下一个唯一组合
//如果'a'已经按降序排列,
//接下来,置换返回false并将数组更改为排序顺序。
//如果可能,现在找到下一个组合
对于(int i=k-1;i>=0;i--){
if(a[i]
参考文献:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
下一个排列:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
下一个无顺序组合:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
不必构建所有排列,因为只有N个/(N-K)!有效的“next_置换函数给出了next字典唯一的置换”。在新创建的数组
A
中有N-k
重复的0
值。所以会有N/(N-k)!独特的排列。伟大的答案!非常感谢。欢迎光临,很高兴它有帮助!如果顺序不重要怎么办?如何才能获得N/(k!(N-k)!)独特的组合?