简体   繁体   中英

Unique permutation pairs from 2 lists (probable combination of two lists)

I have been looking at lot of permutations in Java but I didn't get anything near to my specific requirement. see, I have two lists as follow, list1 and list 2. these list1 and list 2 size can change (But I given here for example list1 carry size 7 and list 2 as size 3)

  //introducing two lists 
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();

//adding data two 1 list
        list1.add("1");
        list1.add("2");
        list1.add("3");
        list1.add("4");
        list1.add("5");
        list1.add("6");
        list1.add("7");

//adding data two 2 list        

        list2.add("a");
    list2.add("b");
    list2.add("c");

The output expected as below combinations and it can be added to list or any collection object

    1:a,2:b,3:c,4:a,5:b,6:c,7:a 
    1:b,2:c,3:a,4:b,5:c,6:a,7:b
    1:c,2:a,3:b,4:c,5:a,6:b,7:c
    so on so....

But these values (rows) should not be duplicated. And in the end all the possible combinations should be covered. I have tried with few for loop logics but it doesn't help.

GUYS,
your help appreciated, but I know this combination: 1:a
1:b 1:c 2:a 2:b 2:c 3:a 3:b 3:c 4:a 4:b 4:c 5:a 5:b 5:c 6:a 6:b 6:c 7:a 7:b 7:c

but the problem I am facing here is
1:a,2:b,3:c,4:a,5:b,6:c,7:a
1:b,2:c,3:a,4:b,5:c,6:a,7:b 1:c,2:a,3:b,4:c,5:a,6:b,7:c so on so....

This is what I want from these lists. Any help?

Your confusion seems to be that you are looping over both lists at the same time. If you set up your loops as outer and inner loops, it should work better

pseudocode:

foreach (e1: elementsOfList1) {
  foreach (e2: elementsOfList2) {
     System.out.println(e1 + ":" + e2);
  }
}
      //introducing two lists 
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();

//adding data two 1 list
list1.add("1");
list1.add("2");
list1.add("3");
list1.add("4");
list1.add("5");
list1.add("6");
list1.add("7");

//adding data two 2 list        

list2.add("a");
list2.add("b");
list2.add("c");

for (String i : list1 ) {
      for (String p : list2) {
           System.out.print(i + ":" + p);
      }
}

A carefully written Iterable can remove all of your future permutations problems:

// A tiny implemetation of a Pair.
public class Pair<P, Q> {

    // Exposing p & q directly for simplicity. They are final so this is safe.
    public final P p;
    public final Q q;

    public Pair(P p, Q q) {
        this.p = p;
        this.q = q;
    }

}

class Permute<P, Q> implements Iterable<Pair<P, Q>> {

    final Iterable<P> ps;
    final Iterable<Q> qs;

    public Permute(Iterable<P> ps, Iterable<Q> qs) {
        this.ps = ps;
        this.qs = qs;
    }

    @Override
    public Iterator<Pair<P, Q>> iterator() {
        return new Iterator<Pair<P, Q>>() {
            // Iterates over the P list.
            Iterator<P> pIterator = ps.iterator();
            // The current p we are pairing with.
            P currentP = null;
            // The current Q iterator - rewinds back after each new P - goes null at end
            Iterator<Q> qIterator = qs.iterator();
            // The next pair to return.
            Pair<P, Q> next = null;

            @Override
            public boolean hasNext() {
                while (next == null && qIterator != null) {
                    // Make sure there's a current P.
                    if (currentP == null) {
                        currentP = pIterator.hasNext() ? pIterator.next() : null;
                    }
                    if (currentP != null) {
                        // Find the next Q to compare it with.
                        if (qIterator.hasNext()) {
                            // Make the new one.
                            next = new Pair<>(currentP, qIterator.next());
                        } else {
                            // Reset the q Itertor.
                            qIterator = qs.iterator();
                            currentP = null;
                        }
                    } else {
                        // Its all over.
                        qIterator = null;
                    }

                }
                return next != null;
            }

            @Override
            public Pair<P, Q> next() {
                if (hasNext()) {
                    Pair<P, Q> nxt = next;
                    next = null;
                    return nxt;
                }
                // No more!
                throw new NoSuchElementException();
            }

        };
    }

}

public void test() {
    List<String> s = Arrays.asList("1", "2", "3", "4", "5", "6", "7");
    List<String> t = Arrays.asList("a", "b", "c");
    for (Pair<String, String> perm : new Permute<>(s, t)) {
        System.out.println(perm.p + ":" + perm.q + ",");
    }
}

Second attempt - getting the order right.

// A tiny implemetation of a Pair.
public static class Pair<P, Q> {

    // Exposing p & q directly for simplicity. They are final so this is safe.
    public final P p;
    public final Q q;

    public Pair(P p, Q q) {
        this.p = p;
        this.q = q;
    }

    public String toString() {
        return "<" + p + "," + q + ">";
    }

}

// My special pair to track permutations already seen.
private static class IntPair extends Pair<Integer, Integer> {

    public IntPair(int p, int q) {
        super(p, q);
    }

    @Override
    public boolean equals(Object it) {
        if (!(it instanceof IntPair)) {
            return false;
        }
        IntPair ip = (IntPair) it;
        return p.equals(ip.p) && q.equals(ip.q);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(p, q);
    }

}

class Permute<P, Q> implements Iterable<Pair<P, Q>> {

    final Iterable<P> ps;
    final Iterable<Q> qs;

    public Permute(Iterable<P> ps, Iterable<Q> qs) {
        this.ps = ps;
        this.qs = qs;
    }

    @Override
    public Iterator<Pair<P, Q>> iterator() {
        return new Iterator<Pair<P, Q>>() {
            // Iterates over the P list.
            Iterator<P> pi = ps.iterator();
            // Where we are in the p list.
            int pn = 0;
            // Iterates over the Q list.
            Iterator<Q> qi = qs.iterator();
            // Where we are in the Q list.
            int qn = 0;
            // The next pair to return.
            Pair<P, Q> next = null;
            // All the pairs we've seen.
            Set<IntPair> seen = new HashSet<>();

            private P nextP() {
                // Step the P list.
                if (!pi.hasNext()) {
                    // Restart p.
                    pi = ps.iterator();
                    pn = 0;
                }
                pn += 1;
                return pi.next();
            }

            private Q nextQ() {
                // Step the P list.
                if (!qi.hasNext()) {
                    // Restart p.
                    qi = qs.iterator();
                    qn = 0;
                }
                qn += 1;
                return qi.next();
            }

            @Override
            public boolean hasNext() {
                if (next == null) {
                    // Make it.
                    next = new Pair<>(nextP(), nextQ());
                    // Have we seen it before?
                    int pCycles = 0;
                    int qCycles = 0;
                    boolean finished = false;
                    IntPair key = new IntPair(pn, qn);
                    while (!finished && seen.contains(key)) {
                        // Add a stagger.
                        if (qi.hasNext()) {
                            next = new Pair<>(next.p, nextQ());
                            if (qn == 1) {
                                qCycles += 1;
                            }
                        } else {
                            next = new Pair<>(nextP(), next.q);
                            if (pn == 1) {
                                pCycles += 1;
                            }
                        }
                        // Finished if we've been around the houses twice.
                        finished = pCycles > 1 || qCycles > 1;
                        key = new IntPair(pn, qn);
                    }
                    if (finished || seen.contains(key)) {
                        next = null;
                    } else {
                        seen.add(key);
                    }
                }
                return next != null;
            }

            @Override
            public Pair<P, Q> next() {
                if (hasNext()) {
                    Pair<P, Q> nxt = next;
                    next = null;
                    return nxt;
                }
                // No more!
                throw new NoSuchElementException();
            }

        };
    }

}

public void test() {
    for (Pair<String, String> perm
            : new Permute<>(
                    Arrays.asList("1", "2", "3", "4", "5", "6", "7"),
                    Arrays.asList("a", "b", "c"))) {
        System.out.print(perm.p + ":" + perm.q + ",");
    }
    System.out.println();
    for (Pair<String, String> perm
            : new Permute<>(
                    Arrays.asList("1", "2", "3"),
                    Arrays.asList("a", "b", "c"))) {
        System.out.print(perm.p + ":" + perm.q + ",");
    }
    System.out.println();
}

prints

1:a,2:b,3:c,4:a,5:b,6:c,7:a,1:b,2:c,3:a,4:b,5:c,6:a,7:b,1:c,2:a,3:b,4:c,5:a,6:b,7:c,
1:a,2:b,3:c,1:b,2:c,3:a,1:c,2:a,3:b,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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