C++ STL Next Permutation with Combination
Posted
技术标签:
【中文标题】C++ 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 实现吗?
【问题讨论】:
***.com/questions/127704/… ***.com/questions/9430568/… ***.com/questions/12991758/… @AlanStokes:所有这些问题都与组合有关;这个问题是关于排列的。 这是关于排列组合的。并且 OP 知道如何排列,这只会留下寻找组合。因此“我正在寻找一种 STL 方式来执行此操作 [...],而不是编写我自己的组合函数”。 【参考方案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
且元素介于 1
和 n
之间的数组的字典顺序。给定任何这样的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
【讨论】:
以上是关于C++ STL Next Permutation with Combination的主要内容,如果未能解决你的问题,请参考以下文章
STL中next_permutation函数的应用-全排列(C++)
STL中next_permutation函数的应用-全排列(C++)
STL中next_permutation函数的应用-全排列(C++)