11. maj 2007 - 09:17Der er
8 kommentarer og 2 løsninger
Sorter ArrayListe efter hyppighed
Hej eksperter,
Jeg sidder med et problem: Jeg har en dynamisk arraylist f.eks. [hej , med , dig] , til denne vil jeg gerne have lavet en mulighed for at få den sorteret i forhold til hvor tit ordene har været brugt.
Jeg skal altså have lavet en anden liste, set, map, hvor frekvensen af hvert ord ligger.
Jeg havde selv tænkt på at lave et hashmap indeholdende strenge som nøgler og værdien skal så være et heltal som repræsentere det antal gange hver streng har været brugt, og så en funktion der hver gang man bruger et ord tilføjer det til hasmappet medmindre det allerede ligger der så skal det bare lægge en til værdien. Dette er ikke så stort et problem.
Der hvor problemet opstår er når jeg skal have min arraylist [hej , med , dig] sorteret i forhold til de værdier jeg kan slå op i mit hashmap. Jeg er helt lost på hvordan dette kan gøres, så har virkelig brug for hjælp.
//create a hashmap with frequencies as keys, and lists of words //with the same frequencies as values HashMap<Integer, ArrayList<String>> bookkeeper = new HashMap<Integer, ArrayList<String>>(); ArrayList<String> samefrequencywords; int frequency; for(String word : frequencies.keySet()){ frequency = frequencies.get(word); samefrequencywords = bookkeeper.get(frequency); if(samefrequencywords == null){ samefrequencywords = new ArrayList<String>(); bookkeeper.put(frequency, samefrequencywords); } samefrequencywords.add(word); }
//sort the individual frequencies ArrayList<Integer> frequencyList = new ArrayList<Integer>(); frequencyList.addAll(bookkeeper.keySet()); Collections.sort(frequencyList);
//create 1 list with all words. same frequency words are //inserted in arbitary order. ArrayList<String> sortedStrings = new ArrayList<String>(); int key; for(int i = 0; i < frequencyList.size(); i++){//bookkeeper.size == frequencyList.size key = frequencyList.get(i); samefrequencywords = bookkeeper.get(key); for(int j = 0; j < samefrequencywords.size(); j++){ sortedStrings.add(samefrequencywords.get(j)); } }
file = open( FName ) worddict = {} # Hash key build in python type
text = file.read().strip()
for line in text.splitlines(): words = line.split() for word in words: if worddict.has_key( word ): worddict[word] = worddict[word] + 1 else: # First time word is found worddict[word] = 1
res_list = worddict.items() res_list.sort(cmp_antal) for ( word, antal ) in res_list: print "%(word)-25s, %(antal)d" % vars()
Jeg har kompilleret med Java 1.6, da koden bruger autoboxing. strings: [a, b, c] frequencies: [a=3, b=5, c=3] bookkeeper: [3=[c, a] 5=[b]]
strings listen bliver ikke brugt til noget, den er med fordi du nævner det i din problemstilling.
frequencyList = [3, 5] i sidste blok i frequencySort metoden: 1.) vi tager de individuelle frekvenser i stigende rækkefølge fra frequencyList, 2.) vi tager de til den givne frekvens hørende liste med strings (disse har samme frekvens) 3.) og sætter dem ind i sortedStrings listen.
For de strings der har samme frekvens er der ikke defineret nogen sorteringsregel.
Fedt iskanu.rigtig fedt, hurtigt om med kommentarer... men hvordan ændre jeg så den sorterer i faldende rækkefølge.? altså de højeste frekvenser først.? har på fornemmelse at det er noget der ligger i collections.sort() kan bare ikke lige gennemskue hvordan..
Jeg har i svaret fokuseret på den centrale problemstilling: sortere efter "values" i din HashMap. Jeg har brugt Collections.sort() for jeg ville ikke implementere en sorteringsalgoritme. Du kan gøre det og få fuld kontrol over sorteringen.
Alternativt kan du bare læse ArrayList'en baglæns: for(int i = sortedStrings.size() - 1, i >= 0; i--){ System.out.println(sortedStrings.get(i)); }
Du kan gøre dette før du sender resultatet retur fra metoden, så main() får det du har specificeret.
# Med revese order file = open( FName ) worddict = {} # Hash key build in python type
text = file.read().strip()
for line in text.splitlines(): words = line.split() for word in words: if worddict.has_key( word ): worddict[word] = worddict[word] + 1 else: # First time word is found worddict[word] = 1
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.