Java декартово произведение - PullRequest
0 голосов
/ 24 апреля 2018

У меня есть класс Main и Xlist<T>, как показано ниже.Я должен сделать декартово произведение от n list.(В данном случае из 3).

Когда я делаю продукт следующим образом:

List<String> list12 = Arrays.asList("a","b");
List<String> list22 = Arrays.asList("X","Y","Z");
List<String> list32 = Arrays.asList("1","2");

cres = XList.computeCombinationsOriginal((Arrays.asList(list12, list22, list32)));
System.out.println(cres);

Он прекрасно работает.И я получаю вывод:

- [[a, X, 1], [b, X, 1], [a, Y, 1], [b, Y, 1], [a, Z, 1], [b, Z, 1], [a, X, 2], [b, X, 2], [a, Y, 2], [b, Y, 2], [a, Z, 2], [b, Z, 2]]

Но когда я хочу сделать это "автоматически" в функциях объединения, я получаю

[[[a, b], [X, Y, Z], [1, 2]]]

Вот весь код.

public class Main {
public static void main(String[] args) {
    // Pewne dodatkowe zestawy danych
    Integer[] ints = {100, 200, 300};
    Set<Integer> set = new HashSet<>(Arrays.asList(3, 4, 5));

    // Sposoby tworzenia
    XList<Integer> list1 = new XList<>(1, 3, 9, 11);

    XList<Integer> list2 = XList.of(5, 6, 9);
    XList<Integer> list3 = new XList(ints);
    XList<Integer> list4 = XList.of(ints);
    XList<Integer> list5 = new XList(set);
    XList<Integer> list6 = XList.of(set);

    System.out.println(list1);
    System.out.println(list2);
    System.out.println(list3);
    System.out.println(list4);
    System.out.println(list5);
    System.out.println(list6);

    // --- i pomocnicze metody do tworzenia z napisów
    XList<String> slist1 = XList.charsOf("ala ma kota");
    XList<String> slist2 = XList.tokensOf("ala ma kota");
    XList<String> slist3 = XList.tokensOf("A-B-C", "-");

    System.out.println(slist1);
    System.out.println(slist2);
    System.out.println(slist3);


    // Metoda union - suma elementów
    List<Integer> m1 =  list1.union(list2);  // oczywiście, można podstawiać na List
    System.out.println(m1);

    // można wykonywać wszystkie operacje z interfejsu List, np:
    m1.add(11);
    System.out.println(m1);

    XList<Integer> m2 = (XList<Integer>) m1;
    XList<Integer> m3 =  m2.union(ints).union(XList.of(4, 4));

    System.out.println(m2); // m2 się nie zmienia
    System.out.println(m3); // wynik jest w m3

    m3 = m3.union(set);
    System.out.println(m3);

    // Widzieliśmy metode union
    // Teraz metoda diff(dowolna kolekcja)
    System.out.println(m3.diff(set));  // wszystko z m3, co nie jest w set
    //System.out.println("m3" + m3);
    System.out.println(XList.of(set).diff(m3)); // co jest w set, czego nie ma w m3

    //set = 3,4,5
    //m3 = [1, 3, 9, 11, 5, 6, 9, 11, 100, 200, 300, 4, 4, 3, 4, 5]
    //wynik = 3,4,5 - 0 = 3,4,5

    // Metoda unique -zwraca nową Xlist bez duplikatow
    XList<Integer> uniq = m3.unique(); // lista, nie Set
    System.out.println(uniq);

    // kombinacje (kolejność jest istotna)
    List<String> sa = Arrays.asList( "a", "b");
    List<String> sb = Arrays.asList( "X", "Y", "Z" );
    XList<String> sc = XList.charsOf( "12" );
    XList toCombine = XList.of(sa, sb, sc);
    System.out.println(toCombine);


    List<List<String>> cres = toCombine.combine();





    List<String> list12 = Arrays.asList("a","b");
    List<String> list22 = Arrays.asList("X","Y","Z");
    List<String> list32 = Arrays.asList("1","2");


    cres = XList.computeCombinationsOriginal((Arrays.asList(list12, list22, list32)));
    System.out.println(cres);

    /*
    // collect i join
    XList<String> j1 = cres.collect( list -> list.join());
    System.out.println(j1.join(" "));
    XList<String> j2 =cres.collect( list -> list.join("-"));
    System.out.println(j2.join(" "));
    */

    // forEachWithIndex
    XList<Integer> lmod = XList.of(1,2,8, 10, 11, 30, 3, 4);
    lmod.forEachWithIndex( (e, i) -> lmod.set(i, e*2));
    System.out.println(lmod);


    lmod.forEachWithIndex( (e, i) -> { if (i % 2 == 0) lmod.remove(e); } );
    System.out.println(lmod);

    lmod.forEachWithIndex( (e, i) -> { if (i % 2 == 0) lmod.remove(i); } );
    System.out.println(lmod); // Pytanie: dlaczego mamy taki efekt?

}
}

А вот класс Xlist:

public class XList<T> extends ArrayList {

private Collection<T> coll;
private List<T> list = new ArrayList<>();
List<T> listTMP;

public XList() {
    coll = new ArrayList<>();
}

public XList(T... arrays) {
    //System.out.println("Pierwszy");
    coll = Arrays.asList(arrays);


}

public XList(T[]... arrays) {
    //System.out.println("drugi");
    coll = new ArrayList<>();
    for (T[] arr : arrays)
        for (T t : arr) {
            coll.add(t);
        }
}

public XList(Collection<T> col) {
    //System.out.println("Trzeci");
    coll = new ArrayList<>();
    coll.addAll(col);
}


@Override
public String toString() {

    return coll.toString();
}

public static <T> XList<T> of(T... arrays) {

    XList<T> tmp = new XList<>(arrays);

    return tmp;
}

public static <T> XList<T> of(T[]... arrays) {

    XList<T> tmp = new XList(arrays);
    return tmp;
}

public static <T> XList<T> of(Collection<T> col) {
    //System.out.println("hashset");
    XList<T> tmp = new XList<>(col);
    System.out.println("of");

    return tmp;
}

public static <T> XList<T> charsOf(T str) {

    Object tab[] = ((String) str).split("");
    XList<T> tmp = new XList<>();
    for (int i = 0; i < tab.length; i++) {
        tmp.coll.add((T) tab[i]);
    }

    return tmp;
}

public static <T> XList<T> tokensOf(T str) {

    Object tab[] = ((String) str).split("\\s");
    XList<T> tmp = new XList<>();
    for (int i = 0; i < tab.length; i++) {
        tmp.coll.add((T) tab[i]);
    }

    return tmp;
}


public static <T> XList<T> tokensOf(T... str) {

    String sep = ((String) str[1]);
    XList<T> tmp = new XList<>();
    for (T t : str) {
        Object tab[] = ((String) t).split(sep);
        for (Object obj : tab)
            tmp.coll.add((T) obj);
    }

    return tmp;
}

public XList<T> union(Collection<T> col) {
    XList<T> returnList = new XList<>();
    if (col instanceof XList) {
        returnList.coll.addAll(this.coll);
        returnList.coll.addAll(((XList) col).coll);
    } else {
        returnList.coll.addAll(this.coll);
        returnList.coll.addAll(col);
    }
    return returnList;
}

public XList<T> union(T... arrays) {


    XList<T> returnList = new XList<>();
    returnList.coll.addAll(this.coll);

    for (T t : arrays)
        returnList.coll.add(t);


    return returnList;

}

@Override
public boolean add(Object obj) {
    coll.add((T) obj);
    return true;
}

public Collection<T> getColl() {
    return coll;
}

public XList<T> diff(Collection<T> col) {
    Collection<T> cpCol = new ArrayList<>();
    cpCol.addAll(this.coll);
    //Wszystko z this co nie jest w col
    if (col instanceof XList) {
        cpCol.removeAll(((XList) col).getColl());
    } else {
        cpCol.removeAll(col);
    }

    XList<T> returnList = new XList<>();
    returnList.coll = cpCol;
    return returnList;
}

public XList<T> unique() {
    XList<T> returnList = new XList<>();
    returnList.coll = this.coll.stream().distinct().collect(toList());
    return returnList;
}


public List<List<T>> combine() {


    List<T> listIterate = new ArrayList<>(this.coll);
    List<List<T>> lista2 = new ArrayList();

    for (int i = 0; i < listIterate.size(); i++){
        List<T> tmp = Arrays.asList(listIterate.get(i));
        lista2.add(tmp);
    }



    return computeCombinationsOriginal(lista2);
}


public static <T> List<List<T>> computeCombinationsOriginal(List<List<T>> lists) {
    List<List<T>> combinations = new ArrayList<>();
    for (List<T> list : lists) {
        List<List<T>> extraColumnCombinations = new ArrayList<>();
        for (T element : list) {
            if (combinations.isEmpty()) {
                extraColumnCombinations.add(Arrays.asList(element));
            } else {
                for (List<T> productList : combinations) {
                    List<T> newProductList = new ArrayList<>(productList);
                    newProductList.add(element);
                    extraColumnCombinations.add(newProductList);
                }
            }
        }
        combinations = extraColumnCombinations;
    }
    return combinations;
}


public static <T> List<List<T>> appendElements(List<List<T>> combinations, List<T> extraElements) {
    return combinations.stream().flatMap(oldCombination
            -> extraElements.stream().map(extra -> {
        List<T> combinationWithExtra = new ArrayList<>(oldCombination);
        combinationWithExtra.add(extra);
        return combinationWithExtra;
    }))
            .collect(Collectors.toList());
}


private List<String> combineTwoLists(List<String> list1, List<String> list2) {
    List<String> result = new ArrayList<String>();
    StringBuilder sb = new StringBuilder();
    for (String s1 : list1) {
        for (String s2 : list2) {
            sb.setLength(0);
            sb.append(s1).append(' ').append(s2);
            result.add(sb.toString());
        }
    }
    return result;
}

public void forEachWithIndex(BiConsumer<T, Integer> bi) {
    listTMP = new ArrayList<>();
    listTMP.addAll(this.coll);

    for (int i = 0; i < listTMP.size(); i++) {
        bi.accept(listTMP.get(i), i);

    }

    this.coll = list;

}

@Override
public Object set(int index, Object obj) {
    //System.out.println(index);
    list.add(index, (T) obj);
    return obj;
}

@Override
public boolean remove(Object obj) {
    //list.remove(obj);
    // System.out.println("kasujemy " + obj);
    this.coll.remove(obj);
    listTMP.remove(obj);
    return true;
}
}

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Может быть, вопрос легче понять.Как мне получить от Collection object до List<List<T>>, чтобы получить именно то, что я получаю здесь

 List<String> list12 = Arrays.asList("a","b");
    List<String> list22 = Arrays.asList("X","Y","Z");
    List<String> list32 = Arrays.asList("1","2");
    cres =  toCombine.computeCombinationsOriginal((Arrays.asList(list12, list22, list32)));

А вот у объекта toCombine есть поле Collection

List<String> sa = Arrays.asList( "a", "b");
    List<String> sb = Arrays.asList( "X", "Y", "Z" );
    XList<String> sc = XList.charsOf( "12" );
    XList toCombine = XList.of(sa, sb, sc);
0 голосов
/ 24 апреля 2018

Может быть, что-то подобное поможет:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *
 * @author David
 */
public class Combine {

    /**
     * @param args the command line arguments
     */
    public static void main( String[] args ) {
        for ( List<Object> li : combine( 
                Arrays.asList( "a", "b" ), 
                Arrays.asList( "X", "Y", "Z" ),
                Arrays.asList( 1, 2 ),
                Arrays.asList( "foo", "bar" ),
                Arrays.asList( true, false ) ) ) {
            System.out.println( li );
        }
    }

    public static List<List<Object>> combine( List<Object> l1, List<Object> l2, List<Object>... moreLists ) {

        List<List<Object>> cp = new ArrayList<>();

        for ( Object o1 : l1 ) {
            for ( Object o2 : l2 ) {
                List<Object> c = new ArrayList<>();
                c.add( o1 );
                c.add( o2 );
                cp.add( c );
            }
        }

        for ( List<Object> other : moreLists ) {

            List<List<Object>> newCp = new ArrayList<>();

            for ( List<Object> ocp : cp ) {
                for ( Object oo : other ) {
                    List<Object> newList = new ArrayList<>();
                    newList.addAll( ocp );
                    newList.add( oo );
                    newCp.add( newList );
                }
            }

            cp = newCp;

        }

        return cp;

    }

}
...