Ich soll eine Tabelle ausgeben, aus der einerseits der Wert, andererseits auch die Häufigkeit des Werts ausgegeben wird. Ergebnis also so:
Wert / Häufigkeit
34 / 5
255 / 2
56 / 1
usw.
Grundsätzlich habe ich das Programm fertig, ABER: meine jeweiligen for-Schleifen führen dazu, dass auch Werte ausgegeben werden, die bereits angezeigt wurden:
Wert / Häufigkeit
34 / 5
255 / 2
255 / 2
56 / 1
usw.
Ich habe keine Idee, wie ich das lösen kann. Bitte helft mir auf die Sprünge, wie ich an die Lösung herangehen soll.
{
public static void main (String args[])
{
int[][]bild = {{34,255,255,56},{127,204,11,34},{123,98,127,34},{34,34,127,17}};
int farbwert, anzahl;
System.out.println("Wert Anzahl");
for (int i = 0; i < bild.length; i++)
{
for (int j = 0; j < bild**.length; j++)
{
farbwert = bild**[j];
anzahl = 0;
for (int x = 0; x < bild.length; x++)
{
for (int y = 0; y < bild[x].length; y++)
{
if (farbwert == bild[x][y]) anzahl = anzahl + 1;
}
}
System.out.println (farbwert + " " + anzahl);
}
}
}
}```
Code
[spoiler]public static void countColors(int[][] picture) { int[] amount = new int[256]; for (int[] row : picture) for (int pixel : row) amount[pixel & 0xFF]++; for (int i = 0; i < amount.length; i++) if (amount** > 0) System.out.println(i + ": " + amount**); }[/spoiler]
Voraussetzung ist aber, dass nur 256 Farben im Bild enthalten sind. Sicherheitshalber habe ich daher & 0xFF mit eingebaut, um eine ArrayIndexOutOfBoundsException zu vermeiden.
Um dir nicht nur eine „Friss und Stirb“-Lösung hinzuwerfen: das Problem ist, dass du für jedes Pixel erneut das gesamte Bild durchzählst. Das ist nicht nur schrecklich ineffizient, sondern sorgt, wie dir ja bereits aufgefallen ist, dafür, dass du für jedes Pixel eine Ausgabe erzeugst.
Die Lösung heißt also: iteriere nur einmal über alle Pixel und speichere für jeden Farbwert die Häufigkeit in einem Array oder einer Map.
Dann iterierst du noch einmal über deine gespeicherten Werte und gibst die Häufigkeiten aus.
Das funktioniert, weil du in dem Array die bereits vorgefundenen Farbwerte speicherst. Wenn du die Anzahl für einen bestimmten Farbwert schon ermittelt hast, dann überspringst du das Pixel einfach.
@author ikwudls
*/
public class ZähleFürMichComp {
private int[] z = new int[256];
public void zähle(int i) {
if (i < 0) {
throw new IllegalArgumentException("" + i);
}
if (i >= z.length) {
int tmp = z.length;
do {
tmp = 1.5;
System.out.println("tmp = " + tmp);
} while (i >= tmp);
int[] y = new int[tmp];
System.arraycopy(z, 0, y, 0, z.length);
z = y;
}
z*++;
}
public int[][] ergebnis() {
int[][] res = new int[z.length][2];
for (int i = 0; i < z.length; i++) {
res**[0] = i;
res**[1] = z**;
}
Arrays.sort(res, new Comparator<int[]>() { @Override
public int compare(int[] o1, int[] o2) {
return -((Integer) o1[1]).compareTo(o2[1]);
}
});
return res;
}
public static void drucke(int[][] res) {
int i = (int) Math.ceil(Math.log10(res.length)) + 1;
for (int[] is : res) {
System.out.format("% “+i+“d”+”% "+i+“d%n”, is[0], is[1]);
}
}
public static void main(String[] args) {
ZähleFürMichComp zfmc = new ZähleFürMichComp();
Random r = new Random();
for (int i = 0; i < 100; i++) {
zfmc.zähle(r.nextInt(10));
}
javaapplication1.ZähleFürMichComp.drucke(zfmc.ergebnis());
}
}```
Jetzt lässt sich darüber streiten, ob ein Konstruktor sinnvoll wäre, ob der Faktor 1,5 sinnvoll ist oder was bei negativen int’s geschehen könnte.
die Lösung von @pl4gu33 hatte ich auch im Kopf, als ich meinen Beitrag geschrieben habe (die Lösung mit der Map). Allerdings habe ich da einen kleinen Kritikpunkt: die Zeilen 25 und 26 finde ich zu “unübersichtlich”.
Wenn man schon auf eine Lösung mit Collections setzt, dann kommt es auf das letzte Quentchen Performance wohl nicht mehr an, sodass man das auch lesbarer formulieren kann:
Das funktioniert, weil du in dem Array die bereits vorgefundenen Farbwerte speicherst. Wenn du die Anzahl für einen bestimmten Farbwert schon ermittelt hast, dann überspringst du das Pixel einfach.
Ich meinte eignetlich das ich ja eigentlich nicht mehr hochzähle, wenn die zahl schon im array ist… :eek:
[QUOTE=cmrudolph]die Lösung von @pl4gu33 hatte ich auch im Kopf, als ich meinen Beitrag geschrieben habe (die Lösung mit der Map). Allerdings habe ich da einen kleinen Kritikpunkt: die Zeilen 25 und 26 finde ich zu “unübersichtlich”.
Wenn man schon auf eine Lösung mit Collections setzt, dann kommt es auf das letzte Quentchen Performance wohl nicht mehr an, sodass man das auch lesbarer formulieren kann:
anzahl = zaehleMap.get(zahl);
zaehleMap.put(zahl, anzahl + 1);```[/QUOTE]
Bei sowas kräuseln sich mit immer die Fußnägel. Ist sicher für eine Aufgabe eine gute Lösungsmöglichkeit, aber im richtigen Leben schreit das geradezu nach einem Multiset (z.B. von Guava).
Habe mir kurz die Interfacedoku vom Multiset angeschaut. Hatte das zwar schonmal durchgelesen, aber noch nicht verwendet und daher wieder vergessen.
Man kann immer nur das benutzen, was man kennt
Insofern: danke nochmal für den Hinweis!