# Elemente in Vector nach Häufigkeit sortieren.



## Zimon (26. Feb 2007)

Hi folks.
Also steinigt mich und esst mich auf, weil ich euch mit soeinem evtl. einfachen unbedeutendem Problem belästige, aber ich habe aktuell ein Brett vorm Kopf!

Folgendes Problem:

Ich habe nen Vector, der String-Elemente enthält. Davon verschiedene in verschiedener Häufigkeit.
Nun möchte ich die Elemente so sortieren, dass das häufigste Element an die erste Stelle des Vectors verschoben wird, und alle doppelten von diesen anschließend gelöscht werden. Das zweihäufigste Element an 2. Stelle usw....

Beispiel:

```
static Vector<String> humm = new Vector();
public static void adden()
	{
		
		humm.add("blub");
		humm.add("sim");
		humm.add("pa");
		humm.add("blub");
		humm.add("blub");
		humm.add("pa");
		humm.add("fi");
	}
```
Nun sieht man, dass "blub" am häufigsten, also 3 mal vorkommt, "blub" soll also an die erste Stelle des vectors verschoben werden.
"pa" an die zweite Stelle und so fort, so dass mein Vector am Ende so aussieht:
humm("blub","pa","sim","fi")

Und das bekomm ich einfach nich hin.

Immo. siehts so aus:

```
public static void sort()
	{
		count=1;
		maxcount=1;
		
		for(int i=0;i<humm.size();i++)
		{
			for (int a=i+1;a<humm.size();a++)
			{
				if (humm.elementAt(i).equals(humm.elementAt(a)))
				{
					count++;
					humm.remove(a);
				}
			}
			if (count>=maxcount)
			{
				maxcount = count;
				humm.add(i, humm.elementAt(i));
			}
			System.out.println(humm.elementAt(i));
		}
	}
```

aber das ist merkwürdiger Weise ne Endlosschleife^^.
Hoffe mir kann jemand weiter helfen, mfg


----------



## SlaterB (26. Feb 2007)

ohne eine zweite Datenstruktur kommst du nicht weit,
du musst dir ja für viele Strings die Länge merken,

das geht z.B. mit einer Map
String -> Anzahl,

erst die Liste durchlaufen und für jedes Vorkommen in der Map die Anzahl für dieses Wort erhöhen,

dann später die Map.Entry-Liste sortieren und deren Strings extrahieren


----------



## Zimon (26. Feb 2007)

Jau, danke schonmal.
Hab ne HashMap benutzt, mein Code sieht dann wie folg aus:

```
public static void sort()
	{
		for(int i=0;i<humm.size();i++)
		{
			count=1;
			for (int a=i+1;a<humm.size();a++)
			{
				if (humm.elementAt(i).equals(humm.elementAt(a)))
				{
					count++;
					humm.removeElementAt(a);
					a--;
				}
			}
			blub.put(humm.elementAt(i), count);
			System.out.println(blub.entrySet());
		}
	}
```
Ausgegeben bekomm ich dabei:

[blub=3]
[blub=3, sim=1]
[blub=3, pa=2, sim=1]
[fi=1, blub=3, pa=2, sim=1]

Jetzt kann ich die wieder Sortieren und in ner Collection o.ä. abspeichern. Wenn ich dabei probleme bekomm, meld ich mich hier nochmal.
Ich markier den also mal noch nicht als gelöst.


----------



## Zimon (3. Mrz 2007)

Tjoa,
gesagt, getan. Denn ich bekomm die obige Ausgabe, also "[fi=1, blub=3, pa=2, sim=1]" nicht sortiert.
Ich find nichtmal nen Ansatz dazu, denn ich kann ja nicht auf die Values 3, 2 und 1 zugreifen, nach denen ich das gerne absteigend sortiert  hätte.
Wäre cool, wenn sich nochmal jemand meinem Problem annehmen könnte!

mfg, der  Zim


----------



## Gelöschtes Mitglied 5909 (3. Mrz 2007)

Hab da mal was ähnliches für dich kopiert, is aber mit einlesen aus ner datei


```
TreeMap<String, Integer> words = new TreeMap<String, Integer>();
LineNumberReader lnr = new LineNumberReader(new FileReader(args[0]));
String line;
int lines = 0; //gesamte anzahl
do {
	line = lnr.readLine();
	if (line != null) {
		lines++;
		Integer counter = words.get(line);
		if (counter == null)
			words.put(line, 1);
		else
			words.put(line, counter.intValue() + 1);
	}
} while (line != null);
// Ausgabe
Iterator<String> iter = words.keySet().iterator();
while (iter.hasNext()) {
	String key = iter.next();
	System.out.println(key + + " " + words.get(key));
}
// Zeilenübersicht ausgeben
System.out.println("============");
System.out.println("Wörter: " + lines);
```


----------



## Marco13 (3. Mrz 2007)

Ja, beim ersten Überfliegen würde ich sagen: das zählt jetzt die Vorkommen, aber gibt sie nicht sortiert aus. 

Für eine sortierte Ausgabe könntest du dir den EntrySet der HashMap holen, und diese Entries in eine ArrayList einfügen, diese ArrayList kannst du dann mit 
Collections.sort(list, new MyComparator());
sortieren, wobei "MyComparator" ein comparator ist, der zwei Map.Entry-Objekte nach ihrer _Vealue_ sortiert.

Aber irgendwie hab ich das Gefühl, dass das insgesamt auch einfacher und effiienter gehen müßte  ???:L


----------



## Wildcard (3. Mrz 2007)

Marco13 hat gesagt.:
			
		

> Aber irgendwie hab ich das Gefühl, dass das insgesamt auch einfacher und effiienter gehen müßte  ???:L


Statt der HashMap eine TreeMap


----------



## Marco13 (3. Mrz 2007)

"Irgendwie müßte das doch mit einer TreeMap gehen" hab ich auch gedacht - die sortiert aber nach den Keys (d.h. den Wörtern) und nicht nach den Values (d.h. der Anzahl)  ???:L


----------



## Wildcard (3. Mrz 2007)

Marco13 hat gesagt.:
			
		

> "Irgendwie müßte das doch mit einer TreeMap gehen" hab ich auch gedacht - die sortiert aber nach den Keys (d.h. den Wörtern) und nicht nach den Values (d.h. der Anzahl)  ???:L


Letztlich ist das eine Sache des Comparators.
Der kann ja auch den Value eines Keys aus der Map holen und den vergleichen.


----------



## Zimon (3. Mrz 2007)

Marco13 hat gesagt.:
			
		

> Ja, beim ersten Überfliegen würde ich sagen: das zählt jetzt die Vorkommen, aber gibt sie nicht sortiert aus.
> 
> Für eine sortierte Ausgabe könntest du dir den EntrySet der HashMap holen, und diese Entries in eine ArrayList einfügen, diese ArrayList kannst du dann mit
> Collections.sort(list, new MyComparator());
> ...



Demnach müsste ich MyComparator selbst schreiben...
Jetzt ist die Frage wie so ein Comparator aussieht, und im Prinzip müsste es doch schon Fertige Comparators für Integer-Werte geben oder nicht ?
Ich check dazu mal die api, und wenn keiner eine einfachere Idee hat, bleibt mir wohl nichts anderes, als das so mal zu versuchen.

Edit:

Ich steh heut etwas auf der Leitung, das holt mir doch die Einträge aus der HashMap in die ArrayList oder ?
arrayList.addAll(hashMap.entrySet());


Edit 2:

Ein Comparator für absteigende Integers würde also so aussehen:

import java.util.Comparator;


```
public class MyComparator implements Comparator<Integer> 
{

	public int compare(Integer o1, Integer o2) 
	{
		int value1 = o1.intValue();
		int value2 = o2;
		
		if(value1>value2)
		return -1;
		else if (value1==value2)
		return 0;
		else
		return 1;
	}

}
```

Edit3:

...was mir aber garnicht weiter hilft xD
Der soll ja die Values von Entrys vergleichen... wie mach ich das nu wieder -.-


----------



## Zimon (3. Mrz 2007)

Also für alle dies nochma genau wissen wollen, der Comparator zum absteigenden sortieren nach Value sieht so aus:


```
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;



public class MyComparator implements Comparator<Map.Entry<String, Integer>> 
{
	public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
		int value1 = o1.getValue();
		int value2 = o2.getValue();
		
		if(value1>value2)
		return -1;
		else if (value1==value2)
		return 0;
		else
		return 1;
	}

}
```


----------



## Marco13 (4. Mrz 2007)

Wildcard hat gesagt.:
			
		

> Marco13 hat gesagt.:
> 
> 
> 
> ...


Ich denke eben gerade NICHT. Der Baum wird ja auf Basis der Keys erst strukturiert (d.h. erst durch die Sortierung nach den Keys wird der Baum zum Baum). Aber ist schon spät - ausprobieren werd' ich das heute nichtmehr.

@Zimon: Ja - und damit müßte das ja jetzt funktionieren, oder?


----------



## Zimon (4. Mrz 2007)

Jop, damit gehts.

Mal ne andere Frage:

Ne Methode die als Parameter das hat (File directory), was bewirkt das, wenn ich die mit ( new File (args[0])) aufrufe ?


----------



## SlaterB (4. Mrz 2007)

eine Operation aufzurufen bewirkt, diese Operation aufzurufen, so dass diese ausgeführt wird,
nicht mehr und nicht weniger??


----------

