简体   繁体   English

如何生成以下序列?

[英]how to generate the following sequence?

I want to generate the following sequence: 我想生成以下序列:

set S = {1,2,3}
op = {{1,2},{1,3},{2,3}}

set S = {1,2,3,4}
op = {{1,2,3},{1,2,4},{1,3,4},{2,3,4}}

set S = {1,2,3,4,5}
op = {{1,2,3,4},{1,2,3,5},{1,2,4,5},{1,3,4,5},{2,3,4,5}}

in general, given a set of n numbers, I have to find all the possible subsets of (n-1) numbers with the constraint that they are in alphabetical order (numbers in order). 通常,给定一组n个数字,我必须找到(n-1)个数字的所有可能子集,并限制它们按字母顺序(数字顺序)。

Is there any algorithm or approach to solve the particular problem? 是否有解决特定问题的算法或方法? I know that we can use recursion to generate smaller subsets. 我知道我们可以使用递归来生成较小的子集。

There are only n such subsets; 这样的子集只有n each one with one of the n original numbers removed from the original set. 每一个都从原始集中删除了n原始编号之一。 So sort the set, and for each of the numbers, create a set which is the original set with that number removed. 因此,对集合进行排序,并为每个数字创建一个集合,该集合是删除了该数字的原始集合。

A possible caveat is that if there are duplicate numbers in the original set, you will only have as many subsets as there are unique numbers in the original set, so possibly fewer than n in that case. 可能的警告是,如果原始集中存在重复的数字,则子集的数目将与原始集中唯一的数目一样多,因此在这种情况下可能少于n

Some languages have this functionality built-in. 某些语言内置了此功能。 For example, Python's itertools.combinations() method . 例如,Python的itertools.combinations()方法 In your case: 在您的情况下:

>>> import itertools
>>> l = [1,2,3,4]
>>> combinations = itertools.combinations(l, len(l) -  1) #for the list of numbers l, for sublists with a length 1 less than l's length
>>> for comb in combinations:
...     print comb
...
(1, 2, 3)
(1, 2, 4)
(1, 3, 4)
(2, 3, 4)
>>>

However, if you want to implement this yourself the link above may still prove useful as it shows equivalent code. 但是,如果您想自己实现,上面的链接可能仍然有用,因为它显示了等效的代码。 You could use this code to make your own implementation in any language. 您可以使用此代码以任何语言进行自己的实现。

This should be simple enough. 这应该足够简单。 Let arr have the sorted set and n be the number of elements: 令arr具有排序的集合,n为元素的数量:

int arr[100];
int n;
printf("{");
for (int i = n - 1; i >= 0; i--){
    printf("{");
    for (int j = 0; j < n; j++) {
        if (i == j) {
            continue;
        }
        printf("%d, ", arr[j]);
    }
    printf("}, ");
}
printf("}\n");

The above prints some additional commas and you can filter them out yourself. 上面打印了一些其他逗号,您可以自己过滤掉它们。

Think about 想一想

  • how to generate the set 1..N 如何生成集合1..N
  • how to identify the number n to be removed from each set (n: N .. 1) 如何识别要从每个集合中删除的数字n (n:N .. 1)

To generate/print a set from 1..N 从1..N生成/打印集

print "{"
for i=1 to N
  if (i > 1) print ","
  print i
end
print "}"

How to create a loop that selects n from N to 1 如何创建一个从N到1中选择n的循环

for j=N to 1 
  ...
end

Use that last loop as a wrapper around that above loop - and in the above loop test if the current selected number j is equal to i and don't print it in that case. 使用最后一个循环作为上述循环的包装器-并在上述循环测试中,如果当前选定的数字j等于i,并且在这种情况下不进行打印。

For the fun a Perl implementation that does not pretend to be optimized :-) 出于乐趣,Perl的实现并没有被优化:-)

$N = 5;

sub rec {
  my($j,$i,@a) = @_;
  if ($j > 0) {
    while (++$i <= $N) { push(@a,$i) if ($i != $j); }
    print('{' . join(',', @a) . "}\n");
    &rec($j-1);
  }
}

&rec($N);

Or this, (maybe) more conventional 还是这个(也许)更传统

for ($i=$N ; $i>0 ; $i--) {
  @a = ();
  for (1..$N) { push(@a,$_) if ($i != $_); }
  print('{' . join(',', @a) . "}\n");
}

In Haskell you could do this : 在Haskell你可以做这个

import Data.List

combinations 0 _  = [ [] ]
combinations n xs = [ y:ys | y:xs' <- tails xs
                           , ys <- combinations (n-1) xs']

subsets set =  combinations (length set - 1) (sort set)


Haskell, briefly: Haskell,简要地:

_                                   =>    anyting
[]                                  =>    empty list
a = 1; as = [2,3]                   =>    a:as = [1,2,3]
[a:b | a <- [1], b <- [[2],[3]]]    =>    [[1,2],[1,3]]
tails [1,2,3]                       =>    [[1,2,3],[2,3],[3],[]]


For example, "combinations 2 [1,2,3]": 例如,“组合2 [1,2,3]”:

tails xs = [[1,2,3],[2,3],[3],[]]

[1,2,3]   =>   y = 1; ys = [[2],[3]]    =>    [1,2],[1,3]
[2,3]     =>   y = 2; ys = [[3]]        =>    [2,3]
[3]       =>   y = 3; ys = NULL         =>    []

Result [[1,2],[1,3],[2,3]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM