假设我有一个包含5个元素的数组。我的程序知道它总是5个元素,当排序时它总是1,2,3,4,5。
根据排列公式,即n!/(n-r)!我们可以用120种方式订购。
在使用std :: next_permutation的C ++中,我可以生成所有这120个订单。
现在,我的程序/例程接受一个输入参数作为1到120范围内的数字,并将数组的特定顺序作为输出。
这适用于小数组大小,因为我可以重复std :: next_permutation,直到匹配输入参数。
真正的问题是,如果我的阵列有25个或更多元素,我怎样才能在更短的时间内完成?对于25个元素,可能的订单数量为:15511210043330985984000000。
是否有一种技术可以使用给定的数字作为输入轻松找到数字的顺序?
提前致谢:)
答案 0 :(得分:0)
我遇到了一个类似的问题,我在Gtk TreeView中存储了很多行,并且每次我想通过它的位置而不是它的引用来访问行时都不想查看所有这些行。
所以,我创建了一个行位置的地图,这样我就可以通过我需要的参数轻松识别它们。
所以,我对此的建议是,您将遍历所有排列并将每个std::permutation
映射到数组中(我使用了std::vector
),因此您可以通过myVector[permutation_id]
访问它。
这是我完成映射的方式:
vector<int> FILECHOOSER_MAP;
void updateFileChooserMap() {
vector<int> map;
TreeModel::Children children = getInterface().getFileChooserModel()->children();
int i = 0;
for(TreeModel::Children::iterator iter = children.begin(); iter != children.end(); iter++) {
i++;
TreeModel::Row row = *iter;
int id = row[getInterface().getFileChooserColumns().id];
if( id >= map.size()) {
for(int x = map.size(); x <= id; x++) {
map.push_back(-1);
}
}
map[id] = i;
}
FILECHOOSER_MAP = map;
}
因此,在您的情况下,您只需迭代这样的排列,您可以通过允许您通过其ID访问它们的方式映射它们。
我希望这会对你有所帮助:D 问候,tagelicht
答案 1 :(得分:0)
这是this link中提到的算法的示例c ++实现:
#include <vector>
#define ull unsigned long long
ull factorial(int n) {
ull fac = 1;
for (int i = 2; i <= n; i++)
fac *= i;
return fac;
}
std::vector<int> findPermutation(int len, long idx) {
std::vector<int> original = std::vector<int>(len);
std::vector<int> permutation = std::vector<int>();
for (int i = 0; i < len; i++) {
original[i] = i;
}
ull currIdx = idx;
ull fac = factorial(len);
while (original.size() > 0) {
fac /= original.size();
int next = (currIdx - 1) / fac;
permutation.push_back(original[next]);
original.erase(original.begin() + next);
currIdx -= fac * next;
}
return permutation;
}
findPermutation
函数接受原始字符串的长度和所需排列的索引,并返回表示该排列的数组。例如,[0, 1, 2, 3, 4]
是长度为5的任何字符串的第一个排列,[4, 3, 2, 1, 0]
是最后一个(第120个)排列。