Arrayproblem

Xknight

Aktives Mitglied
Hallo Leute, ich brauche dringend bei eure Hilfe bei dieser Aufgabe. Die Aufgabe sagt, dass ich aus einem Array den Anteil von positiven, negativen und der Zahl als Dezimalzahl mit 6 Stellen hinter dem Komma angeben soll, aber der Code, den ich geschrieben habe, hat nicht geklappt wie ich es mir erhofft hätte.
Das ist der Input:
  • 6
  • -4 3 -9 0 4 1
und das ist der Output:
  • 0.500000
  • 0.333333
  • 0.166667



Java:
static void plusMinus(int[] arr) {
        int countpos=0;
        for(int elem : arr){
            if(elem > 0){
                countpos++;
            }
        }
        int[] pos = new int[countpos];
        int i = 0;
        for(int elem : arr){
            if(elem > 0){
                elem = pos[i];
            }
        }
        int countneg = 0;
        for(int min : arr){
            if(min < 0){
                countneg++;
            }
        }
        int[] neg = new int[countneg];
        int j = 0;
        for(int min : arr){
            if(min < 0){
                min = neg[j];
            }
        }
        int counteven = 0;
        for(int zero : arr){
            if(zero == 0){
                counteven++;
            }
        }
        int[] neutr = new int[counteven];
        int k = 0;
        for(int zero : arr){
            if(zero == 0){
                zero = neutr[k];
            }
        }
            double posi = pos.length/arr.length;
            double nega = neg.length/arr.length;
            double even = neutr.length/arr.length;
           
            long positiv = (Math.round(posi * 10))/6;
            long negativ = (Math.round(nega * 10))/6;
            long neutral = (Math.round(even * 10))/6;
    }
 
Zuletzt bearbeitet von einem Moderator:
B

BestGoalkeeper

Gast
Schöne Aufgabe für Streams:
Java:
	public static double positives(int... a) {
		return (double) Arrays.stream(a).filter(i -> i > 0).count() / (double) a.length;
	}

	public static double negatives(int... a) {
		return (double) Arrays.stream(a).filter(i -> i < 0).count() / (double) a.length;
	}

	public static double zeros(int... a) {
		return (double) Arrays.stream(a).filter(i -> i == 0).count() / (double) a.length;
	}

	public static void main(String[] args) {
		int[] a = { -4, 3, -9, 0, 4, 1 };
		System.out.printf("%.6f%n%.6f%n%.6f%n", positives(a), negatives(a), zeros(a));
	}
Code:
0,500000
0,333333
0,166667
 
B

BestGoalkeeper

Gast
Oder auch so
Java:
	public static double filterCountAndAvg(IntPredicate predicate, int... a) {
		return (double) Arrays.stream(a).filter(predicate).count() / (double) a.length;
	}

	public static void main(String[] args) {
		int[] a = { -4, 3, -9, 0, 4, 1 };
		System.out.printf("%.6f%n%.6f%n%.6f%n", filterCountAndAvg(i -> i > 0, a), filterCountAndAvg(i -> i < 0, a),
				filterCountAndAvg(i -> i == 0, a));
	}
 

mihe7

Top Contributor
und das ist der Output:
Der Code enthält keinen Output und das, was Dein Code berechnet kann auch nicht zu diesem Output führen (s. unten).

der Code, den ich geschrieben habe, hat nicht geklappt wie ich es mir erhofft hätte.
Die erste Schleife ist ok, danach wird es aber strange. Das Array pos ist überflüssig und die dazu irgendwie in Bezug stehende for-Schleife geradezu unsinnig. Das kannst Du beides weglassen, schließlich hast Du die Anzahl bereits in countpos. Analog gilt dies für die anderen Zähler auch.

Die Rechenfehler ergeben sich allerdings ab dieser Stelle:
Code:
double posi = pos.length/arr.length;
Hier wird eine ganzzahlige Division durchgeführt, weil pos.length und arr.length ganzzahlige Werte sind. Da pos.length <= arr.length gelten muss, ist das Ergebnis entweder 0 oder 1.

Schreib stattdessen:
Java:
double anteilPositiv = countpos / (double) arr.length;
In dem Fall wird eine Ganzzahl countpos durch eine Fließkommazahl geteilt, so dass das Ergebnis eine Fließkommazahl ist.
 
B

BestGoalkeeper

Gast
Oder auch so (würde ich aber nicht empfehlen):
Java:
	public static double sum(IntPredicate predicate, int... a) {
		return Arrays.stream(a).filter(predicate).mapToDouble(i -> 1.0 / a.length).sum();
	}

	public static void main(String[] args) {
		int[] a = { -4, 3, -9, 0, 4, 1 };
		System.out.printf("%.6f%n%.6f%n%.6f%n", sum(i -> i > 0, a), sum(i -> i < 0, a), sum(i -> i == 0, a));
	}
 

Xknight

Aktives Mitglied
BestGoalkeeper können sie mir bitte erklären, was der Befehl und die System.out.printf Ausgabe genau macht?
Code:
(double) Arrays.stream(a).filter(i -> i > 0).count() / (double) a.length;
System.out.printf("%.6f%n%.6f%n%.6f%n"
 
Zuletzt bearbeitet von einem Moderator:

Xknight

Aktives Mitglied
Wie sie erwähnt haben mihe7, habe ich die anderen for-Schleifen rausgelassen und habe die counter für das Dividieren benutzt.
Nun stellt sich auch mir die Frage, ob die Mathefunktionen auch stimmen? Oder ob der gesamte Code fürs erste stimmt?



Code:
  static void plusMinus(int[] arr) {
        int countpos=0;
        for(int elem : arr){
            if(elem > 0){
                countpos++;
            }
        }
      
        int countneg = 0;
        for(int min : arr){
            if(min < 0){
                countneg++;
            }
        }
        int counteven = 0;
        for(int zero : arr){
            if(zero == 0){
                counteven++;
            }
        }

            double posi = countpos/(double) arr.length;
            double nega = countneg/(double) arr.length;
            double even = counteven/(double) arr.length;
            double anteilPos = (Math.round(posi * 10)) / 6;
            double anteilNeg = (Math.round(nega * 10)) / 6;
            double anteilZero = (Math.round(even * 10)) / 6;
 
Zuletzt bearbeitet von einem Moderator:
B

BestGoalkeeper

Gast
Ich bin schon zur Stelle... Also zunächst habe ich NOCH eine Lösung gefunden, die es uns ermöglicht, den Spaß nur einmal zu durchlaufen (Wir sind schon in O(n) aber wir wollen von 3*n wech):
Java:
	private static enum NumberValue {
		GREATER_THAN_0,
		LESS_THAN_0,
		EQUAL_TO_0;

		private static NumberValue getNumberValue(int i) {
			return i < 0 ? LESS_THAN_0 : i > 0 ? GREATER_THAN_0 : EQUAL_TO_0;
		}
	}

	public static void main(String[] args) {
		int[] a = { -4, 3, -9, 0, 4, 1 };

		Map<NumberValue, Long> result = Arrays.stream(a).boxed()
				.collect(Collectors.groupingBy(NumberValue::getNumberValue, Collectors.counting()));

		double l = a.length;
		for (NumberValue value : NumberValue.values()) {
			System.out.printf("%.6f%n", result.get(value) / l);
		}
	}

Jetzt erkläre ich den Spaß... printf gibt etwas formatiert auf der Konsole aus, %f steht dabei für Fließkommazahl, %.6f für Fließkommazahl mit genau 6 Ziffern nachem Komma und %n für einen neuen Zeilenumbruch.
 

Xknight

Aktives Mitglied
Danke, dass sie mir den syso erklärt haben, aber ich wollte ja noch dass sie mir die Methoden erklären vorallem diesen Behfel mir erklären:
Code:
(double) Arrays.stream(a).filter(i -> i > 0).count() / (double) a.length;
 
Zuletzt bearbeitet von einem Moderator:
B

BestGoalkeeper

Gast
Schau doch mal in meine Signatur, ich kann das nicht lesen. Ach so, wir sind hier eigentlich alle per Du.
 
B

BestGoalkeeper

Gast
Man könnte dennoch die drei Schleifen zu einer mergen
Hab ich doch schon getan...

Ups, Schleifen und nicht Streams... ja das könnte er natürlich machen.

Danke, dass sie mir den syso erklärt haben, aber ich wollte ja noch dass sie mir die Methoden erklären vorallem diesen Behfel mir erklären:
Code:
(double) Arrays.stream(a).filter(i -> i > 0).count() / (double) a.length;
Arrays.stream wandelt ein Array in einen Stream um; filter filtert alle Werte raus, die größer 0 sind; count zählt die Anzahl der Vorkommnisse; / (double) a.length teilt durch die Gesamtanzahl der Elems im Array.
 
Zuletzt bearbeitet von einem Moderator:
B

BestGoalkeeper

Gast
Kommt denn das richtige raus?
Nein aber jetzt kann ich's nicht mehr mit ansehen: :eek:
Java:
	public static void plusMinus(int[] arr) {
		int countneg = 0;
		int countpos = 0;
		int counteven = 0;
		for (int elem : arr) {
			if (elem < 0) {
				countneg++;
			} else if (elem > 0) {
				countpos++;
			} else {
				counteven++;
			}
		}

		double posi = countpos / (double) arr.length;
		double nega = countneg / (double) arr.length;
		double even = counteven / (double) arr.length;
		double anteilPos = Math.round(posi * 1000000d) / 1000000d;
		double anteilNeg = Math.round(nega * 1000000d) / 1000000d;
		double anteilZero = Math.round(even * 1000000d) / 1000000d;

		System.out.println(anteilPos);
		System.out.println(anteilNeg);
		System.out.println(anteilZero);
	}
- Wähle bessere Namen als plusMinus, arr und countpos...
- Definiere eine Konstante für 1000000d...
- ?
 

Neue Themen


Oben