Get all 1-k tuples in a n-tuple

前端 未结 3 1066
借酒劲吻你
借酒劲吻你 2021-01-29 04:38

With n=5 and k=3 the following loop will do it

List l=new ArrayList();
l.add(\"A\");l.add(\"B\");l.add(\"C\");l.add(\"D\");l.add(\"E\         


        
相关标签:
3条回答
  • 2021-01-29 05:26

    This technique is called Gosper's hack. It only works for n <= 32 because it uses the bits of an int, but you can increase it to 64 if you use a long.

    int nextCombo(int x) {
      // moves to the next combination with the same number of 1 bits
      int u = x & (-x);
      int v = u + x;
      return v + (((v ^ x) / u) >> 2);
    }
    
    ...
    for (int x = (1 << k) - 1; (x >>> n) == 0; x = nextCombo(x)) {
      System.out.println(Integer.toBinaryString(x));
    }
    

    For n = 5 and k = 3, this prints

    111
    1011
    1101
    1110
    10011
    10101
    10110
    11001
    11010
    11100
    

    exactly as you'd expect.

    0 讨论(0)
  • 2021-01-29 05:26

    Apache commons has iterators for subsets of size k, and for permutations. Here is an iterator that iterates through 1-k tuples of an n-tuple, that combines the two:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.List;
    
    import org.apache.commons.collections4.iterators.PermutationIterator;
    import org.apache.commons.math3.util.Combinations;
    
    public class AllTuplesUpToKIterator implements Iterator<List<Integer>> {
        private Iterator<int[]> combinationIterator;
        private PermutationIterator<Integer> permutationIterator;
        int i;
        int k;
        int n;
    
        public AllTuplesUpToKIterator(int n, int k) {
            this.i = 1;
            this.k = k;
            this.n = n;
            combinationIterator = new Combinations(n, 1).iterator();
            permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));
        }
    
        @Override
        public boolean hasNext() {
            if (permutationIterator.hasNext()) {
                return true;
            } else if (combinationIterator.hasNext()) {
                return true;
            } else if (i<k) {
                return true;
            } else {
                return false;
            }
        }
    
        @Override
        public List<Integer> next() {
            if (!permutationIterator.hasNext()) {
                if (!combinationIterator.hasNext()) {
                    i++;
                    combinationIterator = new Combinations(n, i).iterator();
                }
                permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));          
            }
            return permutationIterator.next();
        }
    
        @Override
        public void remove() {
            // TODO Auto-generated method stub
    
        }
    
        public static List<Integer> intArrayToIntegerList(int[] arr) {
            List<Integer> result = new ArrayList<Integer>();
            for (int i=0; i< arr.length; i++) {
                result.add(arr[i]);
            }
            return result;
        }
    
    
        public static void main(String[] args) {
            int n = 4;
            int k = 2;
            for (AllTuplesUpToKIterator iter= new AllTuplesUpToKIterator(n, k); iter.hasNext();) {
                System.out.println(iter.next());
            }
    
        }
    }
    
    0 讨论(0)
  • 2021-01-29 05:30

    this should be the most efficient way, even if k embedded loops looks ugly

    //singleton
    for (int i = 0; i < l.size(); i++) {
        System.out.println(l.get(i));
    }
    
    //pairs
    for (int i = 0; i < l.size(); i++) {
        for (int j = i+1; j < l.size(); j++) {
            System.out.println(l.get(i)+l.get(j));
        }
    }
    
    //3-tuple
    for (int i = 0; i < l.size(); i++) {
        for (int j = i+1; j < l.size(); j++) {
            for (int k = j+1; k < l.size(); k++) {
                System.out.println(l.get(i)+l.get(j)+l.get(k));
            }
        }
    }
    // ...
    //k-tuple
    
    0 讨论(0)
提交回复
热议问题