如何从组合索引中找到头寸

时间:2018-10-15 03:25:39

标签: c++ math combinations permutation

请耐心等待我尝试解释我要完成的工作。我有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个字词中的哪一种组合可以帮助我。

现在,我正在浏览整个过程以到达那个位置;这效率低下。

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

谢谢您的时间。

1 个答案:

答案 0 :(得分:1)

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


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

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

  • 设置x = 0
  • term1:
    • 如果s1 =“ hello”,则将0加到x
    • 如果s1 =“ greetings”,则将1加到x
    • 如果s1 =“ heya”,则将2加到x
  • term2:
    • x乘以3,即term1的大小
    • 如果s2 =“ is”,则将0加到x
    • 如果s2 =“ are”,则将1加到x
    • 如果s2 =“ you”,则将2加到x
    • 如果s2 =“哇”,则将3加到x
  • term3:
    • 将x乘以4,即term2的大小
    • 如果x =“正在做”,则将0加到x
    • 如果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)

显然,这很容易实现。我将通过编写一个通用版本来接受您和将来的读者的青睐,该版本可以接受任意数量的字符串数组。请注意,这些术语的使用顺序与上述描述相反,同时仍然为每个数字生成唯一列表。

with open(file,'r') as fin:
    f = fin.readlines()
    f = ' '.join(f) # remove newlines
    listrows = f.split('[')
    listrows = [l.split(']')[0] for l in listrows] # Get string between '[' and ']'
    matrix = [row.split('.') for row in listrows] # This is now a 2D matrix
    final = [[int(e.replace(' ','')) for e in row] for row in matrix] # Here goes your final matrix

用法示例:

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;
}