Elvis
Elvis

Reputation: 125

Generate string combinations from string arraylists stored in HashMap

I have a java Hash, the structure is like this:

HashMap<Integer, ArrayList<String>> finalMap = new HashMap<Integer, ArrayList<String>>();

The finalMap.toString() is some thing like this

{0=[a1, a2, a3, a4], 1=[b1, b2, b3], 2=[c1, c2], 3=[d1]}

I need to generate all combination like this:

1. a1 b1 c1 d1
2. a1 b1 c2 d1
3. a1 b2 c1 d1
4. a1 b2 c2 d1
5. a1 b3 c1 d1
6. a1 b3 c2 d1
...
...
...
...
...

Thanks in advance.

Upvotes: 0

Views: 990

Answers (1)

xmoex
xmoex

Reputation: 2702

Simply brute over all elements and skip duplicates (done by HashSet automatically). There are better ways to concat strings but for keeping it simple:

HashSet<String> result = new HashSet<String>();

for (String a : finalMap.get(0)) {
    for (String b : finalMap.get(1)) {
        for (String c : finalMap.get(2)) {
            for (String d : finalMap.get(3)) {
                result.add(a + b + c + d);
            }
        }
    }
}
System.out.println(result);  

Output should be like
[a3b2c1d1, a1b3c1d1, a1b1c1d1, a1b2c2d1, a4b1c2d1, a4b3c2d1, a1b2c1d1, a2b1c2d1, a2b2c2d1, a3b3c2d1, a1b1c2d1, a1b3c2d1, a2b3c2d1, a3b3c1d1, a2b2c1d1, a4b1c1d1, a4b3c1d1, a4b2c1d1, a3b1c2d1, a2b3c1d1, a3b1c1d1, a4b2c2d1, a2b1c1d1, a3b2c2d1]

However if you do not know the total amount of lists yet or if they may vary you could use a recursive approach

void generate(HashSet<String> resultList, String resultString,
        int listNum, HashMap<Integer, ArrayList<String>> data) {
    if (listNum == 0) {
        // start: begin a new resultString
        for (int i = 0; i < data.get(listNum).size(); i++) {
            generate(resultList, data.get(listNum).get(i), listNum + 1,
                    data);
        }
    } else if (listNum == data.size() - 1) {
        // end: store completed resultStrings
        for (int i = 0; i < data.get(listNum).size(); i++) {
            resultList.add(resultString + data.get(listNum).get(i));
        }
    } else {
        // middlepart: append current string to given resultString
        for (int i = 0; i < data.get(listNum).size(); i++) {
            generate(resultList, resultString + data.get(listNum).get(i),
                    listNum + 1, data);
        }
    }
}  

called as follows:

HashSet<String> result = new HashSet<String>();
generate(result2, null, 0, finalMap);
System.out.println(result);  

Output should also be like
[a3b2c1d1, a1b3c1d1, a1b1c1d1, a1b2c2d1, a4b1c2d1, a4b3c2d1, a1b2c1d1, a2b1c2d1, a2b2c2d1, a3b3c2d1, a1b1c2d1, a1b3c2d1, a2b3c2d1, a3b3c1d1, a2b2c1d1, a4b1c1d1, a4b3c1d1, a4b2c1d1, a3b1c2d1, a2b3c1d1, a3b1c1d1, a4b2c2d1, a2b1c1d1, a3b2c2d1]

Upvotes: 1

Related Questions