【问题标题】:How to find position from combination index如何从组合索引中查找位置
【发布时间】:2018-10-15 03:25:38
【问题描述】:

请稍等片刻,我将尝试解释我想要完成的任务。我有一个 n 项的配置。此配置中的每个术语可以具有任意数量的相互不同的元素。例如:

term1 = ["hello", "greetings", "heya"] // 3 elements
term2 = ["is", "are", "you", "wow"] // 4 elements
term3 = ["doing", "now"] // 2 elements

如您所见,每个术语都有不同数量的元素。我可以通过以下方式计算组合总数:

totalSize = term1.size * term2.size * term3.size

我希望能够通过指定位置来自动获取配置。假设我总共有 1000 种可能的组合,我想找出第 500 位的哪些术语组合会得到我。

现在我正在循环整个事情以到达那个位置;这是低效的。

任何建议或见解将不胜感激,

感谢您的宝贵时间。

【问题讨论】:

  • 嗨,杰克,欢迎来到该网站!关于这个问题似乎没有什么是 C++ 特有的。你添加那个标签有什么原因吗?
  • 我希望能在 C++ 中找到解决问题的方法
  • 啊,那么在问题中提及这一点会很有用。尽管如果您似乎只是在寻找算法的描述,人们可能会更好地回答您的问题。有时,当您看起来只是在寻找要复制和粘贴的代码示例时,人们会觉得您很懒惰(不管这是否真的),他们可能不愿意提供帮助。
  • 我添加了 C++ 标志,因为我认为这更像是一个面向编码的问题;我找不到任何通用的“编程”标签——所以我选择了我最熟悉的语言。
  • 好吧,我想这取决于您是想询问 C++ 代码,还是询问解决问题的一般方法。你可以用任何一种方式问这个问题。我只是说现在还不清楚你在问哪个。如果您确实想要求一种通用方法,则根本不需要一个问题具有编程语言的标签或通用标签;你可以只删除 C++ 标签就可以了。但如果你想要一个通用标签,我建议language-agnostic 和/或algorithm

标签: c++ math combinations permutation


【解决方案1】:

要为每个组合有意义地分配一个数字,需要选择一个排序模式。由于有许多组合,并且每个有效排序只是每个可能组合的排列,因此有很多可能的方式来排序这些组合。一种可能的排序方式如下:


输入:分别来自 term1、term2 和 term3 的三个字符串 s1、s2 和 s3 的列表。

输出:0 到 23 之间的唯一整数,或 term1、term2 和 term3 的大小相乘。

  • 设置 x = 0
  • 术语 1:
    • 如果 s1 = "hello",则将 0 添加到 x
    • 如果 s1 = "greetings",则 x 加 1
    • 如果 s1 = "heya",则将 2 添加到 x
  • 术语2:
    • 将 x 乘以 3,即 term1 的大小
    • 如果 s2 = "is",则将 0 添加到 x
    • 如果 s2 = "are",则 x 加 1
    • 如果 s2 = "you",则将 2 添加到 x
    • 如果 s2 = “哇”,则将 3 添加到 x
  • 术语 3:
    • 将 x 乘以 4,即 term2 的大小
    • 如果 x = "doing",则将 x 加 0
    • 如果 x = "now",则将 x 加 1
  • 返回 x

从给定的数字生成一个从 term1、term2 和 term3 的字符串列表只是这个问题的逆过程。下面是对这种算法的描述:


输入:一个数字x

输出:分别来自 term1、term2 和 term3 的三组字符串 s1、s2 和 s3

  • s3:
    • 让 i = x mod 2,term3 的大小
    • 设置 s3 = term3[i]
    • 设置 x = (x - i) / 2
  • s2:
    • 让 i = x mod 4,term2 的大小
    • 设置 s2 = term2[i]
    • 设置 x = (x - 1) / 4
  • s1:
    • 让 i = x mod 3,term1 的大小
    • 设置 s3 = term1[i]
  • 返回 (s1,s2,s3)

显然,这很容易实现。我会通过编写一个接受任意数量的字符串数组的通用版本来帮助你和未来的读者。请注意,这些术语的使用顺序与上述说明相反,但仍会为每个数字生成一个唯一列表。

vector<string> getCombination(const vector<vector<string>>& terms, long x){
    vector<string> result;
    for (const auto& term : terms){
        const long i = x % term.size();
        result.push_back(term[i]);
        x = (x - i) / term.size();
    }
    return result;
}

示例用法:

vector<vector<string>> terms {
    {"hello", "greetings", "heya"},
    {"is", "are", "you", "wow"},
    {"doing", "now"}
};

getCombination(terms, 0);  // -> hello is doing
getCombination(terms, 1);  // -> greetings is doing
getCombination(terms, 2);  // -> heya is doing
...
getCombination(terms, 12); // -> hello is now
...
getCombination(terms, 22); // -> greetings wow now
getCombination(terms, 23); // -> heya wow now

【讨论】:

  • 本质上这是混合基数系统中组合数的表示
猜你喜欢
  • 2014-06-25
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-19
  • 1970-01-01
  • 2017-06-24
相关资源
最近更新 更多