【问题标题】:Permutation for numbers in CC中数字的排列
【发布时间】:2010-09-21 23:26:44
【问题描述】:

我正在尝试编写一个 C 函数来列出一组数字的所有排列,以五个为一组,包括重复数字:

15-11-49-43-5
2-30-34-6-11

所以很容易编写一个函数来抓取一个数字集的所有排列并将它们丢弃,但是映射到某个组大小,我有点卡住了..

【问题讨论】:

  • 你能解释一下“映射到特定组大小”的意思吗?
  • @Niki Yoshiuchi:我认为他的意思是硬编码循环
  • 我的意思是,如果我必须找到 5 组中的 1 到 49 的所有排列。
  • 如中,我有 1 到 49,我想以五个一组的形式打印所有数字的所有组合,允许重复。 Tl;以五人一组的方式将数字 1 - 49 的所有可能组合博士(见示例)
  • 我认为en.wikipedia.org/wiki/Combinatorial_number_system 有您可以使用的信息。

标签: c algorithm permutation combinatorics factorial


【解决方案1】:
void visit(int *Value, int N, int k)
{
  static level = -1;
  level = level+1; Value[k] = level;

  if (level == N)
    print(Value, N);
  else
    for (int i = 0; i < N; i++)
      if (Value[i] == 0)
        visit(Value, N, i);

  level = level-1; Value[k] = 0;
}

更多信息您可以访问http://www.bearcave.com/random_hacks/permute.html

【讨论】:

    【解决方案2】:

    你想得到一个特定的排列,比如 eg

    • 排列 1 == 1, 1, 1, 1, 1
    • 排列 2 == 1, 1, 1, 1, 2
    • 排列 49 == 1, 1, 1, 1, 49
    • 排列 50 == 1, 1, 1, 2, 1
    • 排列 42000000 == 8, 14, 49, 35, 42

    将您想要的数字(减 1)转换为以 49 为底,并使用“数字”(加 1)作为结果。

    42000000 - 1 = 41999999 41999999 = (7 * 49^4) + (13 * 49^3) + (48 * 49^2) + (34 * 49) + 41 结果 8 14 49 35 42

    【讨论】:

      【解决方案3】:

      如果您知道如何找到所有排列但不是所有大小为 5 的组合,那么只需找到以下各项的所有排列:

      int A[49] = { 0, 0, ..., 0, 1, 1, 1, 1, 1 };

      数组 A 的每个排列对应于包含数字 (i+1) 的组合,当且仅当 A[i] == 1,对于 [0, 49) 中的每个 i。

      【讨论】:

        【解决方案4】:

        由于允许重复,并且输出集小于输入集,因此它实际上根本不是您想要的排列。

        您只是在寻找一个简单的计数:

        for (a[0] = 1; a[0] <= 49; a[0]++)
          for (a[1] = 1; a[1] <= 49; a[1]++)
            for (a[2] = 1; a[2] <= 49; a[2]++)
              for (a[3] = 1; a[3] <= 49; a[3]++)
                for (a[4] = 1; a[4] <= 49; a[4]++)
                  printf("%d-%d-%d-%d-%d\n", a[0], a[1], a[2], a[3], a[4]);
        

        【讨论】:

          【解决方案5】:

          我将把它分成两个问题:a) 找到大小为 n 的数组的所有组合 nCk b) 找到长度为 k 的数组的所有排列。您说您已经知道如何进行排列,所以让我们专注于组合:

          void combinations(int *arr, int *comb, int n, int k, int kCurr)
          {
              if(kCurr >= k)
              {
                  permutations(comb, k);
                  return;
              }
              int i;
              for(i=0; i<n; ++i)
              {
                  comb[kCurr] = arr[i];
                  combinations(arr+i, comb, n-i, k, kCurr+1);
              }
          }
          

          会这样调用:

          int myArray[49] = {1, 2, ..., 49};
          int myCombs[5];
          combinations(myArray, myCombs, 49, 5, 0);
          

          这会通过构建数组myCombs 来计算所有组合 49C5,当它已满时,它会调用函数permutations。如果permutations 正确实现,那么您将打印出 49C5 的所有组合的所有排列。

          编辑:Duh,您可以将 combinations(arr, comb, n, k kCurr+1) 作为递归步骤,然后在基本情况下打印数组(或执行任何操作)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-23
            • 1970-01-01
            • 2012-10-11
            相关资源
            最近更新 更多