【问题标题】:generating the cartesian power of a set生成集合的笛卡尔幂
【发布时间】:2012-05-03 03:07:20
【问题描述】:

有没有一种快速的方法来生成集合的笛卡尔幂?

例如,如果集合是 {1, 2},则 {1, 2} x {1, 2} = {(1, 1), (1, 2), (2, 1), (2 , 2)}。对于任何给定的功率,我将如何生成它?

谢谢。

【问题讨论】:

标签: java math


【解决方案1】:

我猜power,你的意思是这个集合与自身组合的频率是多少?所以幂 3 是:

{1, 2} x {1, 2} x {1, 2} = (({1, 2} x {1, 2}) x {1, 2}) 

所以你可以递归解决它,将集合组合一次,然后将集合与结果...

如果您愿意,可以将我的 Iterator for Lists of Lists 改编为 List of Sets ,并构建一个交互器: 导入 java.util.*;

class CartesianIterator <T> implements Iterator <List <T>> {

    private final List <List <T>> lilio;    
    private int current = 0;
    private final long last;

    public CartesianIterator (final List <Set <T>> llo) {
    // transform Set<T> to List <T>, because we need an index later
        List <List <T>> llt = new ArrayList <List <T>> ();    
        for (Set <T> st : llo)
        {
        List <T> lt = new ArrayList <T> ();
        for (T t: st)
            lt.add (t);
        llt.add (lt);
    }
        lilio = llt;
        long product = 1L;
        for (List <T> lio: lilio)
            product *= lio.size ();
        last = product;
    } 

    public boolean hasNext () {
        return current != last;
    }

    public List <T> next () {
        ++current;
        return get (current - 1, lilio);
    }

    public void remove () {
        ++current;
    }

    private List<T> get (final int n, final List <List <T>> lili) {
        switch (lili.size ())
        {
            case 0: return new ArrayList <T> (); // no break past return;
            default: {
                List <T> inner = lili.get (0);
                List <T> lo = new ArrayList <T> ();
                lo.add (inner.get (n % inner.size ()));
                lo.addAll (get (n / inner.size (), lili.subList (1, lili.size ())));
                return lo;
            }
        }
    }
}

class CartesianIterable <T> implements Iterable <List <T>> {

    private List <Set <T>> lilio;  

    public CartesianIterable (List <Set <T>> llo) {
        lilio = llo;
    }

    public Iterator <List <T>> iterator () {
        return new CartesianIterator <T> (lilio);
    }
}

public class SetItTest 
{
    public static void main ( String [] args )
    {
        Set <Integer> si = new HashSet<Integer> ();
        si.add (1);
        si.add (2);
        List <Set<Integer>> ls = new ArrayList <Set<Integer>> ();
        ls.add (si);
        ls.add (si);
        ls.add (si);
        CartesianIterable <Integer> ci = new CartesianIterable <Integer> (ls); 
        for (List <Integer> li : ci) 
        {
            for (int i : li)
                System.out.print (i + " ");
            System.out.println ();
        }
    }
}

输出: java SetItTest

1 1 1 
2 1 1 
1 2 1 
2 2 1 
1 1 2 
2 1 2 
1 2 2 
2 2 2 

【讨论】:

    【解决方案2】:

    如果你可以使用外部库,GuavaSets.cartesianProduct(Set&lt;E&gt;...),所以你可以这样做:

    Set<Integer> set = ImmutableSet.of(1, 2);
    Set<List<Integer>> = Sets.cartesianProduct(set, set);
    // returns {[1, 1], [1, 2], [2, 1], [2, 2]} as desired
    

    (披露:我为 Guava 做出了贡献。)

    【讨论】:

      【解决方案3】:

      您可以尝试使用两个向量 v1 = {x1...xn}, v2 = {y1...yn}

      public List producto(List a, List b) {
          List producto = new ArrayList();
          for (String s1 : a);
              for (String s2 : b) {
                  List duo = new ArrayList();
                  duo.add(s1);
                  duo.add(s2);
                  producto.add(duo);
              }
          }
          return producto;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-09-07
        • 1970-01-01
        • 2012-05-07
        • 2016-10-08
        • 1970-01-01
        • 2020-07-05
        • 2019-03-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多