使用最少的内存和时间查找数组的顺序

Find order of an array using minimum memory and time

本文关键字:时间 查找 数组 顺序 内存      更新时间:2023-10-16

假设我有一个5个元素的数组。我的程序知道它总是有5个元素排序时总是只有1 2 3 4 5个元素。

根据排列公式即n!/(n-r)!我们有120种订购方式。

在c++中使用std::next_permutation,我可以生成所有这120个顺序。

现在,我的程序/例程接受输入参数为1到120范围内的数字,并给出数组的特定顺序作为输出。

对于较小的数组大小可以很好地工作,因为我可以重复std::next_permutation,直到匹配输入参数。

真正的问题是,如果我的数组有25个或更多元素,我怎么能在更短的时间内做到这一点?对于25个元素,可能的订单数量为:15511210043330985984000000。

是否有一种技术,我可以很容易地找到数字的顺序使用一个给定的数字作为输入?

提前感谢:)

这是本链接中提到的算法的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个)排列。

我也遇到过类似的问题,我在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