Zweidimensionales Array sortieren, Häufigkeit ermitteln

jen_81

Mitglied
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.

Java:
  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!
 
S

SlaterB

Gast
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

Top Contributor
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

Mitglied
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.
 
S

SlaterB

Gast
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

Mitglied
... 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...
 
Zuletzt bearbeitet:
S

SlaterB

Gast
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

Top Contributor
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

Top Contributor
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

Top Contributor
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.)

Java:
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 ...
Java:
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
 
Zuletzt bearbeitet:

jen_81

Mitglied
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
Java:
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

Top Contributor
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:
 

jen_81

Mitglied
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.
 
Zuletzt bearbeitet:

ARadauer

Top Contributor
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:

Code:
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?
 

jen_81

Mitglied
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.
 
Zuletzt bearbeitet:

Andi_CH

Top Contributor
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:

Java:
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");
		}
	}
}
 

Neue Themen


Oben