Zahlen nach der Häufigkeit sortieren

tanseleratus

Grünschnabel
Hallo!

Ich habe ein Programm geschrieben in dem 100 Zufallszahlen von 1-20 erstellt werden. Von diesen 100 Zahlen sollen die 5 häufigsten Zahlen heraus gefunden werden und diese der Reihefolge nach sotiert werden.

Dazu habe ich ein einfaches und doch kompliziertes^^ Beispielprogramm geschrieben das so aussieht:

Java:
import java.util.Arrays;

public class Sortierer
{
	public static void main(String[] args)
	{
		String[] temp = new String[20];
		double[] n_temp = new double[20];
		int[] numbers = new int[20],
			  end_numbers = new int[5];
			  
		for(int i = 0; i < 100; i++)
		{
			double n = Math.random()*20;
			numbers[(int)n]++;			
		}
		
		for(int i = 0; i < 20; i++)
		{
            temp[i] = String.valueOf(numbers[i]) + "." + String.valueOf(i+1);
            n_temp[i] = Double.parseDouble(temp[i]);
        }

        Arrays.sort(n_temp);

        for(int i = 15; i < 20; i++)
        {
            temp[i] = String.valueOf(n_temp[i]);
            temp[i] = temp[i].substring(temp[i].indexOf(".")+1,temp[i].length());
            end_numbers[i-15] = Integer.parseInt(temp[i]);
        }

        Arrays.sort(end_numbers);
        
        String str = " Zahlen:";
        
        for(int i = 0; i < 5; i++)
        {
            str += " " + end_numbers[i];
        }
        
        System.out.println(str);
	}
}

nicht schön, aber selten :)

Das Problem dabei ist(was mir erst nach Stunden aufgefallen ist), dass bei der Umwandlung in Double bei den Zahlen 10 und 20 die 0 wegfällt, wenn es in ein String zurück gewandelt wird. Dadurch kommen die Zahlen 1 und 2 zweimal vor.

Habe dann versucht es mit LinkedList, TreeMap, Collections usw. (mit denen ich mich nicht so wirklich gut auskenne) zu machen, aber dabei würden dann immer die Zahlen von 1-20 sortiert und nicht die Häufigkeit.
Als ich es mal geschaft habe mit TreeMap.higherKey() die Häufigkeit zu sortieren, hatte ich dass Problem, dass wenn die Häufkeit bei mehreren Zahlen gleich war, diese in der TreeMap überschrieben würden.

Um nochmal zu verdeutlichen was das Programm tun soll hier ein Beispiel:

100 Zufallszahlen von 1-20 werden erstellt. Davon von kamen die Zahlen sooft vor:

1 = 2x
2 = 5x
3 = 1x
4 = 10x
5 = 6x
... usw.

Die Häufigsten 3 heraussuchen: 4 5 2
Nach der Reihenfolge sotieren: 2 4 5

Hoffe ich habe mein Problem genau genug erklärt um es zu verstehn.
 
Zuletzt bearbeitet:
Hi,

versuchs mal hiermit, sollte funktionieren:

Java:
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class Sortierer {

	public static void main(String[] args) {
		int[] numbers = new int[100];
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		
		// Generiere Zufallszahlen und schreibe Häufigkeiten in die Map:
		for (int i = 0; i < 100; i++) {
			numbers[i] = (int) (Math.random() * 20) + 1;
			
			if (!map.containsKey(new Integer(numbers[i]))) {
				map.put(numbers[i], 1);
			} else {
				map.put(numbers[i], map.get(numbers[i]) + 1);
			}
		}
		
		Set<Integer> ignore = new HashSet<Integer>();
		// Suche die 5 häufigsten heraus:
		for (int i = 0; i < 5; i++) {
			int curMaxKey = 0;
			int curMax = 0;
			
			// Map durchgehen
			Set<Integer> keys = map.keySet();
			for (int k : keys) {
				// Wenn k noch nicht im Ignore-Set ist und der Wert den 
				// höchsten Wert hat...
				if (!ignore.contains(k) && map.get(k) >= curMax) {
					// Ist k der momentan höchste
					curMax = map.get(k);
					curMaxKey = k;
				}
			}
			
			// Den höchsten zum Ignore-Set hinzufügen:
			ignore.add(curMaxKey);
		}
		
		// Das Set in ein Array umwandeln
		Object[] most = ignore.toArray();
		
		// Array sortieren...
		Arrays.sort(most);
		
		// ...und ausgeben
		for (Object i : most) {
			System.out.println(i+" ("+map.get(i)+")");
		}
	}

}
 
Zuletzt bearbeitet:
Hallo,

hier mal ein wenig kompakter:
Java:
package de.tutorials;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;

@SuppressWarnings("unchecked")
public class HistogramExample {

  public static void main(String[] args) {
    List<Comparable> comparables = Arrays.<Comparable> asList(1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,7,7,9,9,9);
    Histogram histogram = new Histogram(comparables);
    histogram.print();
    histogram.printSorted();
  }

  static class Histogram {
    Map<Comparable, Integer> histogram;

    public Histogram(List<Comparable> comparables) {
      this.histogram = new TreeMap<Comparable, Integer>();
      for (Comparable comparable : comparables) {
        this.histogram.put(comparable, Collections.frequency(comparables, comparable));
      }
    }

    public void print() {
      System.out.println(histogram);
    }

    public void printSorted() {
      SortedSet<Map.Entry<Comparable, Integer>> set = new TreeSet<Map.Entry<Comparable, Integer>>(new Comparator<Map.Entry<Comparable, Integer>>() {
        @Override
        public int compare(Entry<Comparable, Integer> left, Entry<Comparable, Integer> right) {
          int result = left.getValue().compareTo(right.getValue());
          return result == 0 ? left.getKey().compareTo(right.getKey()) : result;
        }
      });
      set.addAll(this.histogram.entrySet());
      System.out.println(set);
    }
  }
}

Ausgabe:
Code:
{1=1, 2=2, 3=3, 4=4, 5=5, 6=1, 7=2, 9=3}
[1=1, 6=1, 2=2, 7=2, 3=3, 9=3, 4=4, 5=5]

Gruß Tom
 
Vielen Dank habt mir sehr geholfen. Beide Programme funktionieren super, jetzt muss ich den Code nur noch richtig verstehen lernen;)
 
Zurück