Lists: group duplicates and make new lists acc.to number of duplicates

89 Views Asked by At

Sorry, I'm too tired to figure it out now (too long no sleep), and project deadline is in 1 hour...

I have a lists i.e. like this: {aaa,aaa,bbb,ccc,aaa,bbb,ccc,bbb}. I need to prepare myList defined this way:

List<List<String>> myList = new ArrayList<List<String>>();

to present itself like separate lists according to number of duplicates: {aaa,bbb} {ccc}

here is my ugly code:

int maxAnagramsNumber = 0;
Set<String> unique = new HashSet<String>(anagramLineList);

for (String key : unique) { //set max number of anagrams
    if (maxAnagramsNumber < Collections.frequency(anagramLineList, key)){
        maxAnagramsNumber = Collections.frequency(anagramLineList, key);
    }
}


int countedAnagrams = 0; 

for (int i=maxAnagramsNumber; i > 1; i--){ // group and make new list items acc.to number of duplicates

    for (String anagramUnit : unique){

        if(countedAnagrams != i && countedAnagrams != 0){
            anagramLineListSorted.add(anagramUnit);
        }
        countedAnagrams = i;
    }
    myList.add(anagramLineListSorted);
2

There are 2 best solutions below

2
AbtPst On

all anagrams will have the same set of characters. create a hashmap with the sorted list of chars as key and a list of the actual strings as values. Then finally combine all the values into a single list. try to think how this can be done. i can provide some code if you struggle

pass your original array of strings to this function

Code

public List<String> anagrams(String[] strs) {
    ArrayList<String> result = new ArrayList<String>();
    if(strs == null || strs.length == 0)
        return result;

    HashMap<String, ArrayList<Integer>> map = new HashMap<String, ArrayList<Integer>>();
    for(int i=0; i<strs.length; i++){
        char[] arr = strs[i].toCharArray();
        Arrays.sort(arr);
        String t = String.valueOf(arr);
        if(map.get(t) == null){
            ArrayList<Integer> l = new ArrayList<Integer>();
            l.add(i);
            map.put(t, l);
        }else{
            map.get(t).add(i);
        }
    }

    for(ArrayList<Integer> l: map.values()){
        if(l.size() > 1){
            for(Integer i: l){
                result.add(strs[i]);
            }
        }
    }

    return result;
}

if all you need is to divide the list

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

for(ArrayList<String> l : combined)
    for(String g : l)
        result.add(g);

now result will have all your strings with anagrams grouped together.

0
vvg On

I have not compile it (probably there are some syntax issues). But logic should work as you expect.

int maxAnagramsNumber = 0;
Set<String> unique = new HashSet<String>(anagramLineList);

Map<String, List<String>> ananas = new Map<String, List<Strin>>();

for (String ana:unique) {

    char[] chars = theWord.toCharArray();
    Arrays.sort(chars);
    String key = new String(chars);


    List<String> llist = ananas.get(key)
    if (llist == null) {
        llist = new List<String>()
        ananas.put(key, llist)
    } 
    llist.add(ana)
    }

    println(ananas);