简体   繁体   English

番石榴收藏:限制排列大小

[英]Guava Collections : limit permutation size

Using guava 12 Collections2.permutations() , I'm wondering if it's possible to limit the size of the permutations ? 使用guava 12 Collections2.permutations() ,我想知道是否可以限制排列的大小?

More precisely, I would like to get a list of k-sized permutations within a list of n elements, instead of getting a list of all n-sized permutations. 更准确地说,我想在n个元素的列表中获得k个大小的排列列表,而不是获得所有n个大小的排列的列表。

Currently, if I pass a list of 4 fruits, permutations() will currently return a list of 24 4-sized permutations although I'm only interested in retrieving, say, the 4 unique size 3 permutations. 目前,如果我传递4个水果的列表,那么permutations()将返回24个4大小排列的列表,尽管我只对检索4个唯一大小3个排列感兴趣。

Say I have a list of 4 fruits : 说我有4个水果的清单:

["Banana", "Apple", "Orange", "Peach"]

If I'm only interested in size 3 permutations, I'd like the following returned : 如果我只对3号排列感兴趣,我希望返回以下内容:

["Banana", "Apple", "Orange"]
["Banana", "Apple", "Peach"]
["Banana", "Orange", "Peach"]
["Apple", "Orange", "Peach"]

Could anyone please provide any hints to a solution ? 任何人都可以提供解决方案的任何提示吗? Thanks ! 谢谢 !

This code works out the variations, then runs the permutations on each unique set of 3. 此代码计算出变体,然后在每个唯一的3组上运行排列。

ie for "A", "B", "C", "D" the possibilities are [[A, B, C], [A, B, D], [A, C, D], [B, C, D]]. 即对于“A”,“B”,“C”,“D”,可能性为[[A,B,C],[A,B,D],[A,C,D],[B,C, d]。 We then calculate the permutations on each threesome (or n-some) and append the possibilities to a list. 然后我们计算每个三人组(或n-some)的排列,并将可能性附加到列表中。

PermutationsOfN.processSubsets( List set, int k ) returns: [[A, B, C], [A, B, D], [A, C, D], [B, C, D]] PermutationsOfN.processSubsets(List set,int k)返回:[[A,B,C],[A,B,D],[A,C,D],[B,C,D]]

Taking it a bit further PermutationsOfN.permutations( List list, int size ) returns: 更进一步PermutationsOfN.permutations(List list,int size)返回:
[[A, B, C], [A, C, B], [C, A, B], [C, B, A], [B, C, A], [B, A, C], [A, B, D], [A, D, B], [D, A, B], [D, B, A], [B, D, A], [B, A, D], [A, C, D], [A, D, C], [D, A, C], [D, C, A], [C, D, A], [C, A, D], [B, C, D], [B, D, C], [D, B, C], [D, C, B], [C, D, B], [C, B, D]] [[A,B,C],[A,C,B],[C,A,B],[C,B,A],[B,C,A],[B,A,C],[ A,B,D],[A,D,B],[D,A,B],[D,B,A],[B,D,A],[B,A,D],[A, C,D],[A,D,C],[D,A,C],[D,C,A],[C,D,A],[C,A,D],[B,C, D],[B,D,C],[D,B,C],[D,C,B],[C,D,B],[C,B,D]]

import java.util.Collection;
import java.util.List;

import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

public class PermutationsOfN<T> {
  public static void main( String[] args ) {
    List<String> f = Lists.newArrayList( "A", "B", "C", "D" );
    PermutationsOfN<String> g = new PermutationsOfN<String>();
    System.out.println( String.format( "n=1 subsets %s", g.processSubsets( f, 1 ) ) );
    System.out.println( String.format( "n=1 permutations %s", g.permutations( f, 1 ) ) );
    System.out.println( String.format( "n=2 subsets %s", g.processSubsets( f, 2 ) ) );
    System.out.println( String.format( "n=2 permutations %s", g.permutations( f, 2 ) ) );
    System.out.println( String.format( "n=3 subsets %s", g.processSubsets( f, 3 ) ) );
    System.out.println( String.format( "n=3 permutations %s", g.permutations( f, 3 ) ) );
    System.out.println( String.format( "n=4 subsets %s", g.processSubsets( f, 4 ) ) );
    System.out.println( String.format( "n=4 permutations %s", g.permutations( f, 4 ) ) );
    System.out.println( String.format( "n=5 subsets %s", g.processSubsets( f, 5 ) ) );
    System.out.println( String.format( "n=5 permutations %s", g.permutations( f, 5 ) ) );
  }

  public List<List<T>> processSubsets( List<T> set, int k ) {
    if ( k > set.size() ) {
      k = set.size();
    }
    List<List<T>> result = Lists.newArrayList();
    List<T> subset = Lists.newArrayListWithCapacity( k );
    for ( int i = 0; i < k; i++ ) {
      subset.add( null );
    }
    return processLargerSubsets( result, set, subset, 0, 0 );
  }

  private List<List<T>> processLargerSubsets( List<List<T>> result, List<T> set, List<T> subset, int subsetSize, int nextIndex ) {
    if ( subsetSize == subset.size() ) {
      result.add( ImmutableList.copyOf( subset ) );
    } else {
      for ( int j = nextIndex; j < set.size(); j++ ) {
        subset.set( subsetSize, set.get( j ) );
        processLargerSubsets( result, set, subset, subsetSize + 1, j + 1 );
      }
    }
    return result;
  }

  public Collection<List<T>> permutations( List<T> list, int size ) {
    Collection<List<T>> all = Lists.newArrayList();
    if ( list.size() < size ) {
      size = list.size();
    }
    if ( list.size() == size ) {
      all.addAll( Collections2.permutations( list ) );
    } else {
      for ( List<T> p : processSubsets( list, size ) ) {
        all.addAll( Collections2.permutations( p ) );
      }
    }
    return all;
  }
}

A special mention goes to meriton whose answer here helped me work it out. 特别提到了meriton,他的答案在这里帮助我解决了问题。

There's no built-in Guava feature that does this, though you could submit a feature request . 虽然您可以提交功能请求 ,但没有内置的Guava功能可以执行此操作。

If I were writing an implementation, I think the simplest way would be to iterate through combinations (with Gosper's hack ), and then permutations of those with Collections2.permutations. 如果我正在编写一个实现,我认为最简单的方法是迭代组合(使用Gosper的hack ),然后使用Collections2.permutations进行迭代。

Alternately, it looks like some minor modifications to the normal permutation generation algorithm suffice, based on this Python code . 或者,基于此Python代码 ,看起来对常规置换生成算法的一些小修改就足够了。

A direct answer to your question would be this: 直接回答你的问题是:

public static <X> List<List<X>> test(List<X> input, final int n, final int m) {
    int x = 0;

    List<List<X>> newPerm = Lists.newArrayList();
    Collection<List<X>> perm = Collections2.permutations(input);
    for (Iterator<List<X>> it = perm.iterator(); it.hasNext(); x++) {
        if (x >= n) {
            break;
        }

        List<X> list = it.next();
        newPerm.add(Lists.partition(list, m).get(0));
    }

    return newPerm;
}

and then: 接着:

    List<String> list = Lists.newArrayList("Banana", "Apple", "Orange", "Peach");
    List<List<String>> answer = test(list, 4, 3);
    for (List<String> list1 : answer) {
        System.out.println(list1);
    }

But it takes only the first ones and not a specifically defined set, your probably better off following Louis's advice 但它只需要第一个,而不是一个特别定义的集合,你可能会更好地遵循路易斯的建议

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

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