Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 按需返回n中k个元素的连续组合的算法_Algorithm_Combinations - Fatal编程技术网

Algorithm 按需返回n中k个元素的连续组合的算法

Algorithm 按需返回n中k个元素的连续组合的算法,algorithm,combinations,Algorithm,Combinations,演示如何编写一个算法,一次从n中吐出k个元素的所有组合,避免排列。但是,如何编写一个算法,在不预先计算和存储它们的情况下,根据需要给出下一个组合呢?它将用符号n和整数k的有序集合初始化,然后调用它以返回下一个组合 伪代码或一篇好的英语叙述对我来说很好——除了Perl和C以及一点Java之外,我还不太流利。下面是如何做到这一点的散文描述。从您最喜欢的生成所有组合的迭代算法开始。然后将每个循环变量转换为状态变量,并将其打包为一个类。用k和n构造一个类的实例,并根据算法初始化每个状态变量。下面是如何实

演示如何编写一个算法,一次从n中吐出k个元素的所有组合,避免排列。但是,如何编写一个算法,在不预先计算和存储它们的情况下,根据需要给出下一个组合呢?它将用符号n和整数k的有序集合初始化,然后调用它以返回下一个组合


伪代码或一篇好的英语叙述对我来说很好——除了Perl和C以及一点Java之外,我还不太流利。

下面是如何做到这一点的散文描述。从您最喜欢的生成所有组合的迭代算法开始。然后将每个循环变量转换为状态变量,并将其打包为一个类。用k和n构造一个类的实例,并根据算法初始化每个状态变量。

下面是如何实现这一点的散文描述。从您最喜欢的生成所有组合的迭代算法开始。然后将每个循环变量转换为状态变量,并将其打包为一个类。用k和n构造类的实例,并根据算法初始化每个状态变量。

您可以通过将这些算法转换为。这要求您在连续的nextELement调用之间保存算法的状态


如果您的语言支持协同程序,则可以更轻松地转换代码。Python和C都有一个yield关键字,可以用来将控制权转移回调用函数,同时保留正在执行的算法的状态。

您可以通过将这些算法转换为。这要求您在连续的nextELement调用之间保存算法的状态

如果您的语言支持协同程序,则可以更轻松地转换代码。Python和C都有一个yield关键字,可以用来将控制权转移回调用函数,同时保留正在执行的算法的状态。

原文

跳到下面的更新

让我们假设n个元素是整数1..n。 以递增的顺序表示每个k-组合此表示消除了k-组合中的置换。 现在考虑n个元素的k个组合之间的字典序。换句话说,{i_1..i_k}<{j_1..j_k}如果存在这样的索引t i_s=所有s 求最大索引r,使i_r+1 让我们假设n个元素是整数1..n。 以递增的顺序表示每个k-组合此表示消除了k-组合中的置换。 现在考虑n个元素的k个组合之间的字典序。换句话说,{i_1..i_k}<{j_1..j_k}如果存在这样的索引t i_s=所有s 找到最大的索引r,使i_r可以增加1。 增加索引r处的值,并从i_r+2开始用连续值重置以下元素。 重复此操作,直到无法增加任何位置。 更准确地说:

如果i_k Smalltalk代码

SequenceableCollection >> #nextChoiceFrom: n
    | next k r ar |
    k := self size.
    (self at: 1) = (n - k + 1) ifTrue: [^nil].
    next := self shallowCopy.
    r := (self at: k) = n
      ifTrue: [(1 to: k-1) findLast: [:i | (self at: i) + 1 < (self at: i+1)]]
      ifFalse: [k].
    ar := self at: r.
    r to: k do: [:i | 
      ar := ar + 1.
      next at: i put: ar].
    ^next
原文

跳到下面的更新

让我们假设n个元素是整数1..n。 以递增的顺序表示每个k-组合此表示消除了k-组合中的置换。 现在考虑n个元素的k个组合之间的字典序。换句话说,{i_1..i_k}<{j_1..j_k}如果存在这样的索引t i_s=所有s 求最大索引r,使i_r+1 让我们假设n个元素是整数1..n。 以递增的顺序表示每个k-组合此表示消除了k-组合中的置换。 现在考虑n个元素的k个组合之间的字典序。换句话说,{i_1..i_k}<{j_1..j_k}如果存在这样的索引t i_s=所有s 找到最大的索引r,使i_r可以增加1。 增加索引r处的值,并从i_r+2开始用连续值重置以下元素。 重复此操作,直到无法增加任何位置。 更准确地说:

如果i_k Smalltalk代码

SequenceableCollection >> #nextChoiceFrom: n
    | next k r ar |
    k := self size.
    (self at: 1) = (n - k + 1) ifTrue: [^nil].
    next := self shallowCopy.
    r := (self at: k) = n
      ifTrue: [(1 to: k-1) findLast: [:i | (self at: i) + 1 < (self at: i+1)]]
      ifFalse: [k].
    ar := self at: r.
    r to: k do: [:i | 
      ar := ar + 1.
      next at: i put: ar].
    ^next

你比我快,所以我会简化一下。前两个项目可能是:找到最大的r,使i_r-rng如果i_k增加,则会发生从右到左的进位波动,从而影响最左边的元素。定位该元素后,它可以将元素增加到最左边,然后将元素设置到最右边,使点2所要求的值逐渐增大,以递增的顺序表示每个k组合。。。。所以我认为@rici的简化是有意义的。@Chap:是的,从技术上讲,他的公式只要求你能够比较两个元素并找到一个元素的后续元素。并且可以修改为只需要后续操作。但在实践中,您将在索引向量上执行它,镜像符号向量上的修改。是的s@chap:你可以这样想:想象一根有n个槽口和k个珠子的杆。珠子必须放在槽口里。开始时,所有珠子尽可能靠左。在每次转弯时,您都会找到可以向右移动的最右边的珠子-通常是最右边的珠子-然后将其向右移动一个槽口,并将所有珠子(如果有的话)移动到最左边。继续,直到所有珠子尽可能向右。