das kleinste Element von den Elementen des Array ,die größer gleich den Durchschnitt des Array ist

bradig

Aktives Mitglied
Mein Problem:beim Testen habe ich festgestellt,dass das Programm nicht immer das richtige Ergebnis liefert.(mit dem Array {2,4,4,6,8,12,13} bekomme ich 13 statt 8 )
Bitte um Hilfe.
die Aufgabe:
Gibt die kleinste Zahl des Arrays zurück, die größer oder gleich dem Durchschnitt der Werte des Arrays ist.
Beispiel:
Gegeben das Array {0,1,2,3,4}
Der Durchschnitt der Arrayelemente ist 10/5=2
Die Arrayelemente 3 und 4 sind größer oder gleich diesem Durchschnitt
3 ist die kleinste dieser Zahlen, also wird sie als Ergebnis zurückgegeben.

Java:
public class Average {

 final public static int lowestValueGreaterThanAverage(final int[] arr) {

  int min = 0;
  for (int i = 0; i < arr.length; i++) {
   for (int a: arr) {
    if (arr[i] >= average(arr) && arr[i] < a) {
     min = arr[i];
    }
   }
  }
  return min;
 }

 public static int average(final int[] arr) {
  int sum = 0;
  int r = 0;
  for (int a: arr) {
   sum = sum + a;
  }
  r = sum / arr.length;
  return r;
 }
}
 
Zuletzt bearbeitet von einem Moderator:
K

kneitzel

Gast
Also bitte code immer in Code-Tags setzen. Dann fallen mir folgende Probleme auf:
a) Wieso hast Du zwei verschachtelte Schleifen? Wenn Du den Durchschnitt hast, dann musst Du doch nur einmal durch das Array gehen!
b) Du musst dir einmal das min merken und immer nur damit vergleichen. min setzt du am Anfang einfach auf den größten Integer Wert, der möglich ist und schon hast Du als Prüfung doch nur: Wenn der Wert größer ist als der Durchschnitt und kleiner ist als das aktuelle Minimum, dann setze das Minimum auf den Wert.

Ansonsten noch eine Optimierung: Die Berechnung des Durchschnitts geht ja immer durch das ganze Array. Da sich aber während deiner Suche nach den kleinsten Wert der größer als der Durchschnitt ist sich ja nichts ändert am Array macht es Sinn, den Wert einmal zu bestimmen und nicht für jede Prüfung neu zu berechnen.
 

Viktim

Bekanntes Mitglied
So müsste es eigentlich klappen:

Java:
  public static void main(String[] args) {
    int[] array = { 6, 2, 9, 5, 2, 7};
    int arrayGesamtWert = 0;

    for (int i = 0; i < array.length; i++) {
      arrayGesamtWert = arrayGesamtWert + array[i];
    }

    int durchSchnittsWert = (arrayGesamtWert / array.length);
    int kleinsteZahlÜbermDurchschnitt = 999999999;
    for (int i = 0; i < array.length; i++) {
      if (array[i] == durchSchnittsWert) {
        kleinsteZahlÜbermDurchschnitt = array[i];
        break;
      }
      if (array[i] > durchSchnittsWert && array[i] < kleinsteZahlÜbermDurchschnitt) {
        kleinsteZahlÜbermDurchschnitt = array[i];
      }
    }

    System.out.println("Durchschnitt: "+ durchSchnittsWert
        + "\nKleinste Zahl überm Durchschnitt ist: " + kleinsteZahlÜbermDurchschnitt);

  }

Du musst hier nur noch dein Array entsprechend Anpassen :D
 
Zuletzt bearbeitet:

bradig

Aktives Mitglied
Danke .ich habe es dank dir hinbekommen.
soll man auch hier die richtige Ergebnisse posten,wenn man es am Ende hinbekommen hat?
 
K

kneitzel

Gast
Deine Lösung wäre schon interessant. Ist aber natürlich keine Pflicht. Nur bitte als Code, also im Editor oben auf das Einfügen Icon klicken und Code auswählen. Dann kannst Du auch noch Java als Sprache wählen wenn Du willst.
 

bradig

Aktives Mitglied
Java:
public class Average {

 final public static int lowestValueGreaterThanAverage(final int[] arr) {
  int min = maximum(arr);
  for (int i = 0; i < arr.length; i++) {
   if (arr[i] >= average(arr) && arr[i] < min) {
    min = arr[i];
   }
  }
  return min;
 }

 public static int average(final int[] arr) {
  int sum = 0;
  int r = 0;
  for (int a: arr) {
   sum = sum + a;
  }
  r = sum / arr.length;
  return r;
 }
 public static int maximum(final int[] arr) {
  int max = 0.0;
  for (int a: arr) {
   if (a >= max) {
    max = a;
   }
  }
  return max;
 }
}
 
Zuletzt bearbeitet von einem Moderator:
K

kneitzel

Gast
Gefällt mir sehr gut, nur ein paar Kleinigkeiten würde ich anders machen:

Java:
    final public static int lowestValueGreaterThanAverage(final int[] arr) {
        int min = Integer.MAX_VALUE; // No need to iterate through array with maximum(arr);
        int average = average(arr); // Only executed one time now!
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] >= average && arr[i] < min) {
                min = arr[i];
            }
        }
        return min;
    }

    public static int average(final int[] arr) {
        int sum = 0;
        int r = 0;
        for (int a: arr) {
            sum = sum + a;
        }
        r = sum / arr.length;
        return r;
    }
  
    public static int maximum(final int[] arr) {
        int max = 0; // Just 0 - 0.0 is a double!
        for (int a: arr) {
            if (a >= max) {
                max = a;
            }
        }
        return max;
    }

Sind nur paar Kleinigkeiten, aber evtl. willst Du die ja noch abändern.
Und generell würde ich bei Funktionen immer ein Verb mit benutzen, also getMaximum, getAverage, getXYZ, doSomething, ... Aber das habe ich im Code nicht angepasst, da die Namen ja evtl. vorgegeben waren.
 

Joose

Top Contributor
Ich glaub ja ;) Das erste Mal um den Durchschnitt zu berechnen und beim zweiten Mal werden dann die einzelnen Elemente mit dem Durchschnitt verglichen.
Wenn du natürlich ähnlich verständlichen Code mit nur einen Durchlauf kennst, dann her damit.
 

Flown

Administrator
Mitarbeiter
Witzige Aufgabenstellung. Lösung ist schon gepostet, wie man das per Hand macht. Wollte einfach mal mein Verusch mit ein paar Collection/Stream API calls zusammenfassen:
Java:
/**
 * Computes the least value greater or equal to the average of the given
 * array.
 * 
 * @param arr
 *          the array of values
 * @return the least element greater than or equal to the average
 * @throws NullPointerException
 *           if the given array is {@code null}
 * @throws NoSuchElementException
 *           if the given array is empty (i.e. {@code arr.length == 0})
 */
public static int getLowestAboveOrEqualsAverage(int[] arr) {
  Objects.requireNonNull(arr);
  if (arr.length == 0) {
    throw new NoSuchElementException();
  }
  NavigableSet<Integer> set = new TreeSet<>();
  int sum = Arrays.stream(arr).peek(set::add).sum();
  return set.ceiling(sum / arr.length);
}
 
X

Xyz1

Gast
Wow! Also danke euch für die Antworten... Zuerst hab ich einfach gelesen: ALLE, die größer gleich des Durchschnitts sind. Aber so macht es sinn.

Dann noch etwas:
http://stackoverflow.com/questions/...on-then-sort-it-or-add-to-a-sorted-collection
http://stackoverflow.com/questions/23329234/which-is-better-on-log-n-or-on2

That means n^2 grows faster, so n log(n) is smaller (better), when n is high enough.

Das heißt, Flown's Algo ist schneller, wenn es soundsoviele Inhalte gibt.

Bis dann :)

Edit: Sorry, ich hab mich mit der Komplexität vertan. Bin heute zu müde.
 

bradig

Aktives Mitglied
Java:
public class Average {

final public static int lowestValueGreaterThanAverage(final int[] arr) {
  int min = Integer.MAX_VALUE;
int aver=average(arr) ;
  for (int i = 0; i < arr.length; i++) {
   if (arr[i] >= aver && arr[i] < min) {
    min = arr[i];
   }
  }
  return min;
}

public static int average(final int[] arr) {
  int sum = 0;
  int r = 0;
  for (int a: arr) {
   sum = sum + a;
  }
  r = sum / arr.length;
  return r;
}

}
 
Zuletzt bearbeitet:

bradig

Aktives Mitglied
Mit MAX_VALUE brauche ich nicht extra eine Funktion schreiben,die das maximum berechnen.
Danke an euch allen.
hier kann man echt viele Sachen lernen.
:) Daum hoch für dieses Forum.
 

Flown

Administrator
Mitarbeiter
Gestern nicht mehr dazu gekommen. Man kann ein paar Sachen noch verbessern:
Java:
/**
* Gibt das kleinste Element größer oder gleich dem arithmetischen Mittelwert
* zurück.
*
* @param arr
*          angegebene Zahlenfolge
* @return kleinste Element größer oder gleich dem arithmetischen Mittelwert
* @throws NullPointerException
*           wenn {@code arr == null} ist
* @throws NoSuchElementException
*           wenn {@code arr} leer ist
*/
final public static int lowestValueGreaterThanAverage(final int[] arr) {
  if (arr == null) {
    throw new NullPointerException();
  }
  if (arr.length == 0) {
    throw new NoSuchElementException();
  }
  int aver = average(arr);
  int min = Integer.MAX_VALUE;
  for (int element : arr) {
    if (aver == element) {
      return aver;
    } else if (aver < element && element < min) {
      min = element;
    }
  }
  return min;
}

/**
* Berechnet das ganzzahligen arithmetischen Mittelwert.
*
* @param arr
*          angegebene Zahlenfolge
* @return das arithmetische Mittel oder {@code 0} falls {@code arr} leer ist
*      
* @throws NullPointerException
*           wenn {@code arr == null} ist
*/
public static int average(final int[] arr) {
  if (arr == null) {
    throw new NullPointerException();
  }
  if (arr.length == 0) {
    return 0;
  }
  int sum = 0;
  for (int a : arr) {
    sum = sum + a;
  }
  return sum / arr.length;
}
Ein paar Checks sollten schon eingebaut sein für die Corner-Cases. Darüber hinaus kann man ein shortcircuit Verhalten einbauen, d.h. kleiner als der Durschnitt geht nicht und man kann gleich das Element zurückgeben.
Man kann auch nur ein Element finden, wenn das Array nicht leer ist.
Achja und ein paar JavaDoc-Worte währen auch nicht schlecht.
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Also Dein Code dürfte einen Fehler enthalten.
Du prüfst erst ob das erste Element = dem Durchschnitt ist. Kann man machen, ok.
Dann setzt Du min = arr[0]. Das ist falsch, denn arr[0] kann ja auch kleiner als der Durschschnitt sein.

Wenn man also { 1, 2, 5, 6 } nimmt, dann gibst Du die 1 zurück, da Du ja min am Anfang auf 1 setzt und dann gibt es kein Element mehr, das Größer als der Durchschnitt ist und kleiner als min.
 

Neue Themen


Oben