2D Arrays summieren

JavaKev

Mitglied
Hallo, ich habe folgende Aufgabe bekommen: Schreiben Sie eine Methode sumUpCols, die ein 2D-double-Array x als Parameter erwartet (das Array ist Zeilenweise aufgebaut). Die Methode soll ein 2D-double-Array mit genauso vielen Zeilen aber nur einer Spalte zurückgeben. Jedes dieser Spaltenelemente soll die Summe der zugehörigen Zeile von x enthalten. Sie können davon ausgehen dass das Array mindestens eine Spalte enthält.

Nun habe ich folgenden Code geschrieben:
Code:
public static double[][] sumUpCols(double[][] x){
           double[][] neuerString = new double[x.length][0];
           double sumRow = 0.0;
           if (x.length == 0.0) return new double[0][0];
           for (int i = 0; i < x.length; i++) {
               for (int j = 0; j < x[i].length; j++) {
                    sumRow += x[i][j]; 
                }
               neuerString[i][0] = sumRow;
           }
           return neuerString;
        }
ich bekomme hier leider wieder mal eine ArrayOutOfBoundsException was ich aber nicht verstehen kann. Kann mir jemand auf die Sprünge helfen?
Getestet habe ich mit :
Code:
System.out.println(Arrays.deepToString(sumUpCols(new double[][] {})));
System.out.println(Arrays.deepToString(sumUpCols(new double[][] { { 1., 1. }, { 2., 2. }, { 3., 3. } })));
 
Und BITTE kümmere dich um die Benennung deiner Variablen: double[][] neuerString = new double...

Die war beim letzten Mal schon fragwürdig, aber diesmal ist sie grottig. Ein double-Array mit dem Namen neuerString????
 
Noch eine Kleinigkeit. Man sollte Variablen so spät wie möglich deklarieren.
Java:
double[][] neuerString = new double[x.length][0];
double sumRow = 0.0;
// wenn der Parameter nicht korrekt ist, dann brauchst du auch die Variablen nicht
if (x.length == 0.0) return new double[0][0];


//Besser:

if (x.length == 0.0) return new double[0][0];
// dann werden die Variablen gar nicht erst initialisiert, weil die Methode vorher verlassen wird
double[][] neuerString = new double[x.length][0];
double sumRow = 0.0;
 
ich bekomme hier leider wieder mal eine ArrayOutOfBoundsException was ich aber nicht verstehen kann. Kann mir jemand auf die Sprünge helfen?
Benutzt du eine IDE? Dann solltest du dich unbedingt mit den Debugging-Funktionen vertraut machen. Außerdem wird dir in der Meldung der Exception auch eine Zeilennummer genannt, mit der du recht zielgerichtet an die betroffene Stelle gelangst.
 
Außerdem wird dir in der Meldung der Exception auch eine Zeilennummer genannt, mit der du recht zielgerichtet an die betroffene Stelle gelangst.
In diesem Fall wird aber der Fehler in der Zeile angezeigt (wahrscheinlich auch im Debugger), in der auf das Array zugegriffen wird. Der "wahre" Fehler liegt aber in der Zeile (weit vorher), in der das Array erzeugt wird.

Es bedarf schon einiger Erfahrung, solche Fehlermeldungen richtig zu interpretieren.
 
In diesem Fall wird aber der Fehler in der Zeile angezeigt (wahrscheinlich auch im Debugger), in der auf das Array zugegriffen wird. Der "wahre" Fehler liegt aber in der Zeile (weit vorher), in der das Array erzeugt wird.
Damit hast du Recht; man gelangt zur Zuweisung, aber an dieser Stelle muss man sich Gedanken machen, was daran falsch sein könnte. "sumRow" kann es nicht sein, bleibt die Zuweisung übrig. Dann kann man noch mal über "i" nachdenken und kontrollieren, ob es den gültigen Bereich verlassen kann. Ist das ausgeschlossen bleibt nur noch das Array selbst übrig.
 
So hätte ich das gemacht. Das funktioniert aber nur(!!!) wenn das 2D-Array rechteckig ist:
Java:
	public static double[][] sumUpCols(double[][] x) {
		double[][] r = new double[x[0].length][1];
		for (int i = 0; i < x[0].length; i++) {
			double sum = 0;
			for (int j = 0; j < x.length; j++) {
				sum += x[j][i];
			}
			r[i][0] = sum;
		}
		return r;
	}

	public static void main(String[] args) {
		double[][] x = {
				{  1,  2,  3, 9, 9, 9 },
				{  4,  5,  6, 9, 9, 9 },
				{  7,  8,  9, 9, 9, 9 },
				{ 10, 20, 30, 9, 9, 9 },
				};
		x = sumUpCols(x);
		for (double[] ds : x) {
			System.out.println(Arrays.toString(ds));
		}
	}

Verbesserungen?
 
Der Code ist wunderschön! 🙂
Allerdings verstehe ich nicht, warum Du dich auf ein Rechteck beschränkst, wenn Du mit ein Paar Änderungen jede Form abfangen kannst...

Java:
    public static double[][] sumUpCols(double[][] x) {
        double[][] r = new double[x.length][1];
        
        for (int i = 0; i < x.length; i++) {
            double sum = 0;
            
            for (int j = 0; j < x[i].length; j++) {
                System.out.println(sum);
                sum += x[i][j];
            }
            r[i][0] = sum;
        }
        return r;
    }
 
Das hatte ich auch erst.
Java:
	public static double[][] sumUpCols(double[][] x) {
		double[][] r = new double[x.length][1];

		for (int i = 0; i < x.length; i++) {
			double sum = 0;

			for (int j = 0; j < x[i].length; j++) {
				System.out.println(sum);
				sum += x[i][j];
			}
			r[i][0] = sum;
		}
		return r;
	}

	public static void main(String[] args) {
		double[][] x = {
				{ 1, },
				{ 2, 3, },
				{ 4, 5, 6, },
				};
		x = sumUpCols(x);
		for (double[] ds : x) {
			System.out.println(Arrays.toString(ds));
		}
	}

Aber Du berechnest jetzt nicht mehr Spaltensummen sondern Reihensummen!
 
So jetzt aber:
Java:
	public static double[][] sumUpCols(double[][] x) {
		double[][] a = Stream.of(x).sorted((a0, a1) -> a1.length - a0.length).toArray(double[][]::new);
		double[][] r = new double[a[0].length][1];

		for (int i = 0; i < a[0].length; i++) {
			double sum = 0;
			for (int j = 0; j < a.length && i < a[j].length; j++) {
				sum += a[j][i];
			}
			r[i][0] = sum;
		}
		return r;
	}

	public static void main(String[] args) {
		double[][] x = { { 1, }, { 2, 3, }, { 4, 5, 6, }, };
		x = sumUpCols(x);
		for (double[] ds : x) {
			System.out.println(Arrays.toString(ds));
		}
	}

@temi Nein es sollten die Spaltensummen berechnet werden. Ich bin doch nicht doof. 😛
 
Die Aufgabe lautet, die Summe der zugehörigen Zeile zu berechnen.
Jedes dieser Spaltenelemente soll die Summe der zugehörigen Zeile von x enthalten.
Ich bin doch nicht doof.
Tatsächlich bist du nicht doof, denn du hast bemerkt, dass der Name der Methode nicht zur Aufgabe passt. 😉
Die Methode heißt sumUpCols...
Möglicherweise wurde aber auch der Text der Aufgabe fehlerhaft widergegeben.
 
Wer gerade Lust und Zeit hat, ich habe mal danach gefragt, wie man diese Methode vollständig in Streams umwandeln könnte, also nur mit Streams schreiben könnte (ich hoffe nicht, dass die Frage wieder downgevoted wird):
 
Sorry @MoxxiManagarm aber jemand anderes ist besser 😉
Java:
	public static double[] sumUpCols(double[][] x) {
		return Arrays.stream(x)
				.flatMap(b -> IntStream.range(0, b.length)
						.mapToObj(i -> new AbstractMap.SimpleEntry<Integer, Double>(i, b[i])))
				.collect(Collectors.groupingBy(e -> e.getKey(), Collectors.summingDouble(v -> v.getValue()))).values()
				.stream().mapToDouble(d -> d).toArray();
	}

	public static void main(String[] args) {
		System.out.println(Arrays.toString(sumUpCols(new double[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 5, 4 } })));
	}

Das gefällt mir schon gut. 🙂
 

Zurück
Oben