# Zweidimensionales Array sortieren, Häufigkeit ermitteln



## jen_81 (26. Jan 2011)

Hallo zusammen,

nach langem hin und her, Tagelangem ausprobieren ohne Erfolg hoffe ich, ihr könnt mir einen kleinen Tipp zu meinem Problem geben. Bin absoluter Java Einsteiger. 
Die Aufgabe klingt so simpel, ist sie wahrscheinlich auch, aber ich kriegs nich hin. 

Folgende Aufgabe:

int Werte in einem zweidimensionalen Array sollen mit ihrer Häufigkeit in einer Tabelle ausgegeben werden.


```
import java.util.Arrays;


class Bildverarbeitung 
{
 public static void main (String args[])
  {
 
   int farbwert [][]={
                      {34,255,255,56},
                      {127,204,11,34},
                      {123,98,127,34},
                      {34,34,127,17}
                      };
```

Als Beispiel zu diesem Thema hatte ich vorher nur eine selection sort Aufgabe. Keine Ahnung wie die Sortierung hier funktioniert, geschweige denn das Ermitteln der Häufigkeiten. Es fehlen natürlich noch die Schleifen, aber dann hörts bei mir auch schon auf.
Arrays.sort funktioniert ja nicht für Mehrdimensionale Arrays. Habe nach dem Hinweis auf die Klasse Arrays etwas von comparator gefunden, was vielleicht hier richtig ist. Ich weis aber nicht wie ich es anwenden muss. Ich erwarte natürlich keinen kompletten Code, aber für eine Hinweis wäre ich dankbar, damit ich wenigstens einmal anfangen kann. 
Merci im Voraus!


----------



## SlaterB (26. Jan 2011)

bevor du es programmieren kannst musst du wissen was rauskommen soll, ich wüßte jetzt nicht, wie das gegebene Array 'sortiert' aussehen soll,
hast du da schon eine Vorstellung? 
vielleicht alle Zahlen in ein größeres eindimensionales Array übernehmen, das sortieren und die Zahlen dann wieder auf die Plätze des 2D-Arrays verteilen?


---

zu Häufigkeit: kannst du das denn bei einem eindimensionalen Array?
wie würdest du auf dem Papier bei einer vor dir liegenden Liste von Zahlen vorgehen?


----------



## ARadauer (26. Jan 2011)

Zum sortieren... ich würde auch wie Slater geschrieben hat, das in ein 1 Dim Array wandeln -> sortierne - > zurück

Zum Zählen... darfst du die Java Collecíon API versenden? Wenn ja, würde ich mir das HashSet ansehen.
Ist ein Wert als schlüssel nicht drinnen, fügst du ihn als Schlüssel mit dem Wert 1 ein
Ist er drinnen fügst du ihn als Schlüssel mit dem aktuellen Wert +1 ein


----------



## jen_81 (26. Jan 2011)

Also, hab mir das Ganze natürlich auf ein Papier gekritzelt und das Ergebnis sollte wie geschrieben eine Tabelle sein, mit den sortierten Werten Links, und der Anzahl rechts. Ich stell mir das so vor:

Farbwert    Häufigkeit/Vorkommen

11                1
17                1
34                5
56                1
98                1
123               1
127               3
204               1
255               2       

Wobei die Werte sortiert sind und nicht mehrfach aufgelistet werden. Momentan schaffe ich es nur mir alles unsortiert ausgeben zu lassen, sprich das gesamte Array.
Ausser den Verweis auf die Klasse Arrays, die ganz supi sortier Methoden haben soll, hab ich halt den Wissensstand von "selection sort". Und dann folgte diese Aufgabe. Da HashSet bisher nicht dran kam, denke ich eher nicht das ich das verwenden darf.


----------



## SlaterB (26. Jan 2011)

deiner Liste nach ist es anscheinend egal, ob sich ein Wert in einer bestimmten Zeile oder Spalte befindet,
also ist die Erkenntnis, alles in ein Array zu kopieren, vorerst zementiert,
das ist erstmal eine Aufgabe mit Schleifen,
danach dann nur noch über ein eindimensionales Array nachdenken:
[c] int f2 []={34,255,255,56,127,204,11,34,123,98,127,34,34,34,127,17};[/c]
ohne HashSet oder ähnliches wäre Sortieren nun wirklich angebracht, ob du dafür eigenen Code verwendest und Fragen dazu hast oder Arrays.sort(), das musst du entscheiden

danach kannst du dann das Array durchgehen, aktuelle Werte anschauen, wenn im nächsten Feld gleich dann Zähler hochzählen,
beim Wechsel Wert in ein neues Array übernehmen wo jeder Wert dann nur noch einmal auftaucht + Anzahl, also vielleicht 2D-Array,
alles eine Frage von Schleifen, Variablen, if/else


----------



## jen_81 (26. Jan 2011)

SlaterB hat gesagt.:


> ... alles in ein Array zu kopieren, vorerst zementiert,
> das ist erstmal eine Aufgabe mit Schleifen...
> 
> ...beim Wechsel Wert in ein neues Array übernehmen wo jeder Wert dann nur noch einmal auftaucht + Anzahl, also vielleicht 2D-Array...
> ...alles eine Frage von Schleifen, Variablen, if/else



Mhm, und wie kopiere in das in ein neues Array? Ich hab keine Ahnung wie ich da rangehen soll. Haben das alles auch noch gar nicht durchgenommen. Also Schleifen, Variablen und Co. natürlich schon, aber Felder kopieren und Werte in neue Arrays übernehmen? Da tauchen ja zig neue Fragen auf...


----------



## SlaterB (26. Jan 2011)

meinetwegen sogar nur das eine Array wiederverwenden oder die Daten während der Schleife nur berechnen und gleich ausgeben,
alles noch im Rahmen des denkbaren,
immer weiter will ich nicht alles verraten, fang doch mal mit bisschen Code an,

z.B. mit einer Schleife ein Array durchlaufen und die Zahlen ausgeben, 
und z.B. hinter jede Zahl ausgeben, ob der aktuelle Wert größer als der vorherige im Array ist, 
dahingehend schon was möglich?


----------



## Marco13 (27. Jan 2011)

Bei den Namen "Bildverarbeitung" und "Farbwert" drängen sich die Fragen auf, ob es da nur um Werte zwischen 0 und 256 geht (was ich mal vermute). Dann ist das, was da berechnet werden soll, einfach das "Histogramm", und kann mit einem int[256] erledigt werden...


----------



## ARadauer (27. Jan 2011)

> Haben das alles auch noch gar nicht durchgenommen.


ja hoffentlich ;-) habt ihr nicht alles was man mit so einer schleife machen kann durchgenommen ...



> Da tauchen ja zig neue Fragen auf...


welche?
1. du brauchst also ein neues array?
2. wie groß? die summe der längen der einzelnen arrays in dem 2 dim array...
    mach das mal, also eine schleife über das zweidiminsinale array und die längen zussamen zählen.
3. über das zwei dimensionale array mit zwei verschachtelten schleifen drüber gehen und die werte in das neue array nacheinander einfügen..


----------



## Andi_CH (27. Jan 2011)

Marco13 hat gesagt.:


> Bei den Namen "Bildverarbeitung" und "Farbwert" drängen sich die Fragen auf, ob es da nur um Werte zwischen 0 und 256 geht (was ich mal vermute). Dann ist das, was da berechnet werden soll, einfach das "Histogramm", und kann mit einem int[256] erledigt werden...



Das dauerte aber lange bis zu der Erkenntnis ;-)

und falls es nicht so ist rase ich halt erst einmal durch die Farbwerte und suche das Maximum raus. (siehe unten)

(Ja logisch - es gibt auch geeignetere Datenstrukturen aber hier im Anfängerbereich ist Array schon gut.)


```
class Bildverarbeitung 
{
	public static void main (String args[])
	{
		int farbwert [][]={
				{34,255,255,56},
				{127,204,11,34},
				{123,98,127,34},
				{34,34,127,17}
		};

		int [] histo = new int[256];

		for (int i=0; i<histo.length; i++) {
			histo[i] = 0;
		}
		// Musst halt mal Nachdenken was hier wohl sein muss
		for(int i=0; i<pArr.length; i++) {
			for(int j=0; j<pArr[i].length; j++) {
				//entsprechendes Feld in histo eines hochzählen
				// Tipp: Zugriff auf farbwert[i][j] ...
			}
		}
		System.out.println("Häufigkeiten:");
		for (int i=0; i<histo.length; i++) {
			if (histo[i] != 0)
				System.out.println("Wert " + i + " kommt " + histo[i] + " mal vor");
		}
	}
}
```

Adaptiver Wertebereich ...

```
class Bildverarbeitung 
{
	private static int maximalwert(int[][] pArr) {
		int value = 0;
		for(int i=0; i<pArr.length; i++) {
			for(int j=0; j<pArr[i].length; j++) {
				if (pArr[i][j] > value)
					value = pArr[i][j];
			}
		}
		return value;
	}

	public static void main (String args[])
	{

		int farbwert [][]={
				{34,255,255,56},
				{127,204,11,34},
				{123,98,127,34},
				{34,34,127,17}
		};

		final int max = maximalwert(farbwert);

		int [] histo = new int[max];
// weiter gehts wie oben
```


----------



## trez (27. Jan 2011)

```
int [] histo = new int[max+1];
```


----------



## Andi_CH (27. Jan 2011)




----------



## jen_81 (27. Jan 2011)

Ja es geht ums Histogramm. Sorry, hätt ich auch gleich sagen können.
Vielen Dank für eure Mühen, aber irgendwie scheints bei mir nicht anzukommen.


Mir fällt zum fehlenden Code nur 

```
if (farbwert[i][j]==(histogramm[i]))
        histogramm[i]=histogramm[i]+1;
```

ein. 
Was ja nicht funktionieren kann, liefert ja auch kein Ergebnis. 
Ich weis ich muss mir alle Werte von farbwert_[j] ansehen und den Zähler für entsprechenden Wert in meinem neuen "Hilfs-"Array "histogramm" erhöhen. Immernoch absolut keinen Schimmer wie ich das hinkriegen soll, wie ich das eine mit dem anderen in Verbindung bringe.
Sorry, ich Java Nixblicker._


----------



## Andi_CH (28. Jan 2011)

Falsch! Und das hat rein gar nichts mit Java zu tun! Aber nicht im Geringsten. Mach die Augen auf und mutiere vom Nichtblicker zum Durchblicker.
Unter Vorarbeit für eine solche Aufgabe verstehe ich eben Eclipse BlueJ oder was auch immer abschiessen - erst mal Aufgabe lesen und auf Papier überlegen was man will (Das dauert mindestens so lange wie das anschliessende Codieren.)

Also zur Lösung:

Wir wandern in den zwei for Schlaufen durch die Bilddaten. ok?
Auf Position _[j] steht ein Wert - nehmen wir mal an es sei 42 (Also 42 kommt vor)
Demzufolge muss doch einfach im histo auf Position 42 eins hochgezählt werden. (Das ist übrigens ein Einzeiler!)

histo[42] += 1; -> und jetzt nur noch die 42 durch den inidizierten Zugriff auf die Bilddaten ersetzen.

So, somit ist das Ganze zu einem Exmatrikulationsbeispiel verkommen :bahnhof:_


----------



## ARadauer (28. Jan 2011)

Andi_CH hat gesagt.:


> So, somit ist das Ganze zu einem Exmatrikulationsbeispiel verkommen :bahnhof:


Von wem hast du wohl dieses Wort ;-)

Wie Andi_CH schon gesagt hat... im grunde ist farbwert_[j] die Postiton im Histrogramm Array die erhöht werden muss_


----------



## jen_81 (28. Jan 2011)

Also, ich sitze doch schon seit Wochen vor diesem Scheiß und versuche es auf Papier zu lösen, oder direkt mit Code. Ich kann es nicht. Ich bin nicht sofort beim ersten Problem hier ins Forum gekommen und erwarte das ihr mir die komplette Lösung serviert, das will ich auch jetzt nicht. Ich weis was theoretisch gemacht werden müsste und trotzdem kriege ich es nicht auf die Reihe das in Code umzuwandeln. Bisher hat das alles immer wunderbar gepasst, jetzt bin ich an der Grenze. Und siehe da:





> So, somit ist das Ganze zu einem Exmatrikulationsbeispiel verkommen


Schon wieder was, was ich nicht verstehe. 
Aber ein verlockender Gedanke geradezu...

Vielen Dank für eure Mühe.


----------



## Andi_CH (28. Jan 2011)

ARadauer hat gesagt.:


> Von wem hast du wohl dieses Wort ;-)



Von wem wohl


----------



## ARadauer (28. Jan 2011)

Exmatrikulationsbeispiel  nicht verstehen ist schlecht ;-)
Bedeutet im Grunde: Wenn ich das Beispiel nicht schaffe, kann ich gleich schon exmatrikulieren (=von der Uni abmelden)



> trotzdem kriege ich es nicht auf die Reihe das in Code umzuwandeln



wenn dus wirklich schon wochenlang probierst, hier mal die lösung:


```
import java.util.Arrays;

public class Histogramm {

   public static void main(String[] args) {
      int farbwert[][] = { {34, 255, 255, 56}, {127, 204, 11, 34}, {123, 98, 127, 34}, {34, 34, 127, 17}};
      
      int[] hist = new int[256];
      for (int i = 0; i < farbwert.length; i++) {
         for (int j = 0; j < farbwert[i].length; j++) {
            hist[farbwert[i][j]]++;
         }
      }

      System.out.println(Arrays.toString(hist));
   }
}
```

Im Grunde nicht schwer! Schau dir das hist[farbwert_[j]]++; mal an kannst du das nachvollziehen?

Also 
int wert =farbwert[j];
hist[wert]++;

Lass dich nicht entmutigen... Falls das das erste Semester ist, würd ich auf keinen Fall aufgeben, vielleicht machts ja im Frühling "klick" also nicht gleich exmatrikuleren nur weil wir das sagen ;-)

Was studierst du genau?_


----------



## ARadauer (28. Jan 2011)

Andi_CH hat gesagt.:


> Von wem wohl




Bin mir nicht mal mehr sicher ob mir das Wort selber eingefallen ist:
radauer.com Blogarchiv  Das Exmatrikulations-Beispiel

Wir hatten einen Prof auf der FH der hatte an seinem Büro ein Schild hängen "Das Exmatrikulations-Büro" Also wenn du bei dem deinen Nachprüfung hattest könntes du einen Mietvertrag im Studentenheim schon kündigen... ;(


----------



## jen_81 (28. Jan 2011)

Keine Sorge, was Exmatrikulieren bedeutet verstehe ich noch gerade so.
Natürlich werde ich mich nicht entmutigen lassen.
Aber solche Reaktionen sind genau der Grund weshalb ich so lange gezögert hab hier eine Frage zu stellen.:bahnhof: 
Ich studiere per Fernstudium im ersten Semester Web- und Medieninformatik. Nach meiner Ausbildung zur Informatikkauffrau.


----------



## ARadauer (28. Jan 2011)

> Ich studiere per Fernstudium im ersten Semester Web- und Medieninformatik.


Ja dann auf keinen Fall entmutigen lassen!
Da ist es wichtiger du kannst super mit Photoshop, PHP, CSS und javascript umgehen...


----------



## jen_81 (28. Jan 2011)

Es war wirklich nur            


```
hist[farbwert[i][j]]++;
```

was mir gefehlt hat? Oh mann - 
Danke!


----------



## Andi_CH (28. Jan 2011)

jen_81 hat gesagt.:


> Aber solche Reaktionen sind genau der Grund weshalb ich so lange gezögert hab hier eine Frage zu stellen.:bahnhof:


Du solltest eben nicht nur fragen sondern auch signalisieren, dass du mitdenkst - von dir kam keine einziger Hinweis das du etwas versucht hast und das ist hier immer schlecht.

Es gibt hier eine bestimmte Anzahl user die, sorry wenn ich es so direkt sage, vor Faulheit stinken und nur die fertige Lösung wollen - das frustet einen und prägt auch.

Bemerkungen wie "Javanixblicker" "steh auf dem Schlauch" "blutiger Anfänger" oder was sonst noch so kommt bringen nichts, vor allem dann nicht, wenn das eigentliche Problem rein gar nichts mit Java zu tun hat sondern nur damit, dass man die Aufgabe nicht mal auf dem Papier zu lösen versucht hat.

Jede Wette - schmeiss Java erst mal auf die Seite und lös die Aufgabe auf dem Papier - du wirst sehen du findest eine Lösung und kannst die danach auch in ein Programm umsetzen.
Erst auf dem Papier (Warum glaubt mir das niemand ???:L :bahnhof dann ist alles viel einfacher.
(Man kann es gar nicht oft genug sagen.)

Dann kommen plötzlich Fragen wie
"Ich hab das versucht aber es kommt die Exeption XY"
"Würdet ihr das anders lösen, wie geht es eleganter" 
"Welches Javakonstrukt eignet sich für ....."

Ich hatte die Lösung shon bevor die Bemerkung mit 255 kam, aber dir ist am wenigsten geholfen wenn du die fertige Lösung bekommst, denn du bist am lernen.

Ach ja lernen besteht zu einem grossen Teil aus Widerholungen:

Wichtigster Punkt - egal welches Problem: Erst auf dem Papier lösen!
Umsetzen in Java, C oder was auch immer ist dann viel einfacher.

So, hier noch der Ansatz der auch mit Wertebereichen grösser als 255 fertig würde:


```
package com.javaforum.statisitk;

class Bildverarbeitung 
{
	private static int maximalwert(int[][] pArr) {
		int value = 0;
		for(int i=0; i<pArr.length; i++) {
			for(int j=0; j<pArr[i].length; j++) {
				if (pArr[i][j] > value)
					value = pArr[i][j];
			}
		}
		return value;
	}

	public static void main (String args[])	{

		int farbwert [][]={
				{34,255,255,56},
				{127,204,11,34},
				{123,98,127,34},
				{34,34,127,17} };

		final int max = maximalwert(farbwert);
		int [] histo = new int[max+1];
		for (int i=0; i<histo.length; i++) {
			histo[i] = 0;
		}
		for (int i=0; i<farbwert.length; i++) {
			for(int j=0; j<farbwert[i].length; j++) {
				histo[farbwert[i][j]]++;
			}
		}
		System.out.println("Häufigkeiten:");
		for (int i=0; i<histo.length; i++) {
			if (histo[i] != 0)
				System.out.println("Wert " + i + " kommt " + histo[i] + " mal vor");
		}
	}
}
```


----------

