【问题标题】:C++ STL Next Permutation with CombinationC++ STL Next Permutation with Combination
【发布时间】:2016-09-15 14:14:26
【问题描述】:

我知道我可以在包含元素 [1, 2, 3] 的某个容器上使用 std::next_permutation,这将生成此序列的 6 个排列。我想要做的是给定一些集合[1, 2, 3, 4, 5, 6] 生成所有可能的大小为 3 的排列。因此对于这个例子,[4, 3, 2] 将是这个标准产生的排列之一。我正在寻找一种 STL 方式来做到这一点(如果可能的话),而不是编写我自己的组合函数。我应该阅读任何特定的 STL 实现吗?

【问题讨论】:

标签: c++ algorithm stl combinations permutation


【解决方案1】:

目前(截至 2016 年)没有单一的 STD 功能可以做到这一点。你最接近的是来自http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2639.pdf的建议

你想要的函数叫做next_partial_permutation,看起来像(来自N2639):

template  <class  BidirectionalIterator >
bool next_partial_permutation(
  BidirectionalIterator  first ,
  BidirectionalIterator  middle ,
  BidirectionalIterator  last)
{
  std::reverse(middle , last);
  return std::next_permutation(first , last);
}

【讨论】:

    【解决方案2】:

    这不是最有效的算法,但它很容易。您必须从已排序的元素开始。要获得下一个 k 排列,请反转最后 n-k 个元素,然后尝试获得下一个排列。前 k 个元素是下一个 k 排列。

    【讨论】:

    • 你这么说似乎很明显,+1。
    【解决方案3】:

    这是一个用 Smalltalk 编写的算法。

    该算法的思想是考虑长度为 m 且元素介于 1n 之间的数组的字典顺序。给定任何这样的array,方法next 用它按所述顺序的下一个部分排列替换array

    我创建了一个包含三个实例变量的类

    array       the current permutation of length m
    m           the size of array
    complement  the SortedCollection of integers not in array
    

    实例创建方法m:n:工作原理如下

    m: length n: limit
      m := length.
      array := (1 to: m) asArray.
      complement := (m + 1 to: limit) asSortedCollection
    

    在这个类中,next 方法修改了array,以便它现在可以保存下一个排列。

    值得一提的是该算法不是递归的。

    next 方法以 nil 回答,但 array 包含顺序中的最后一个排列(即 array = (n, n-1, ...., n-m+1)

    要计算所有排列,从array = (1 ... m) 开始并发送next,直到答案为nil

    next
      | index max h a c |
      index := self lastDecreasingIndex.
      max := complement max.
      h := (index to: m) findLast: [:i | (array at: i) < max] ifAbsent: nil.
      h isNil
        ifTrue: [
          index = 1 ifTrue: [^nil].
          a := array at: index - 1.
          index to: m do: [:i | complement add: (array at: i)].
          c := complement detect: [:cj | a < cj].
          array at: index - 1 put: c.
          complement remove: c; add: a.
          index to: m do: [:i | array at: i put: complement removeFirst]]
        ifFalse: [
          h := h + index - 1.
          a := array at: h.
          c := complement detect: [:ci | a < ci].
          array at: h put: c.
          complement remove: c; add: a.
          h + 1 to: m do: [:i | complement add: (array at: i)].
          h + 1 to: m do: [:i | array at: i put: complement removeFirst]]
    

    在哪里

    lastDecreasingIndex
      | index |
      index := m.
      [(array at: index - 1) > (array at: index)] whileTrue: [
        index := index - 1.
        index = 1 ifTrue: [^1]].
      ^index
    

    【讨论】:

      猜你喜欢
      • 2021-05-15
      • 2022-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-15
      • 2022-01-10
      • 1970-01-01
      相关资源
      最近更新 更多