解决nPr(置换)的算法。对于假人

时间:2016-03-13 01:42:24

标签: algorithm recursion permutation

是的,我是RTFM。或者,在这种情况下,RTFSO。如果它出现在" npr"的搜索结果中或者"排列",我读了它。虽然我已经实现了Heap算法,但我无法从那里(所有排列)跳跃到nPr(长度为r的所有排列,从更大的集合n中)。

实际算法(伪代码很好)比不包含实际代码的冗长解释更受欢迎。如果你想让我了解理论,那很好,我很乐意从中学习,但我也喜欢附带的代码。如果你能说出Heap's,那就太好了;否则,我会糊里糊涂。

我没有任何代码可以告诉你(除非你想看到在VBScript中实现Heap(这是我必须在工作中工作的))因为,正如我所说,我不知道#39;知道从那里去哪里获得集合n的每个r长度子集。

如果我对nPr的描述不足,这里有一个非常简单的例子,说明我要做的事情:

考虑到设定......

A,B,C

...我想找到每个两个字符的排列,如下:

A B
A C
B C

这个例子过于简单化,因为我真正想要得到的是一个通用的解决方案,它采用一个集合(数组),以及每个排列中应该包含的项目数量,作为调用参数。

嗯......现在我已经把这一切写出来了,在我看来,我真的只需要知道如何从集合n中导出长度为r的所有子集,因为我可以找到它的排列那些使用Heap的子集。

仅供参考:我今年会年满50岁;这不是家庭作业。

1 个答案:

答案 0 :(得分:2)

递归相对简单:

  • 对于集合中的每个元素,使用与否。
  • 与两个变体的其余部分一起递归。
  • 结果完成时停止或剩余设置为空。
  • 为了提高性能,请使用开始/位置索引避免实际的设置操作。

在JavaScript中:

function nPr(set, n) {
  nPrImpl(set, 0, new Array(n), 0);
}

function nPrImpl(set, pos, result, resultPos) {

  // result complete
  if (resultPos == result.length) {
    window.console.log(result);
    return;
  } 

  // No more characters available
  if (pos >= set.length) {
    return;
  }

  // With set[pos]
  result[resultPos] = set[pos];
  nPrImpl(set, pos + 1, result, resultPos + 1);

  // Without
  nPrImpl(set, pos + 1, result, resultPos);
}

// Test:
nPr(['A', 'B', 'C'], 2);

输出:

["A", "B"]
["A", "C"]
["B", "C"]

演示:https://tidejnet.appspot.com/v3/#id=8ht8adf3rlyi