Ermitteln des Max / Min-Werts in einem Array von Grundelementen mithilfe von Java


184

Es ist trivial, eine Funktion zu schreiben, um den Min / Max-Wert in einem Array zu bestimmen, wie zum Beispiel:

/**
 * 
 * @param chars
 * @return the max value in the array of chars
 */
private static int maxValue(char[] chars) {
    int max = chars[0];
    for (int ktr = 0; ktr < chars.length; ktr++) {
        if (chars[ktr] > max) {
            max = chars[ktr];
        }
    }
    return max;
}

aber ist das nicht schon irgendwo gemacht?


8
Ein Array von primitiven zu Array von Containern würde helfen: stackoverflow.com/questions/3770289/… gefolgt von Collections.max(Arrays.asList()).
Ciro Santilli 法轮功 冠状 病 六四 事件 13

Ich liebe es einfach, wie dumm Java ist
Farid

Antworten:


172

Verwenden von Commons Lang (zum Konvertieren) + Sammlungen (zu min / max)

import java.util.Arrays;
import java.util.Collections;

import org.apache.commons.lang.ArrayUtils;

public class MinMaxValue {

    public static void main(String[] args) {
        char[] a = {'3', '5', '1', '4', '2'};

        List b = Arrays.asList(ArrayUtils.toObject(a));

        System.out.println(Collections.min(b));
        System.out.println(Collections.max(b));
   }
}

Beachten Sie, dass Arrays.asList()das zugrunde liegende Array umbrochen wird, damit es nicht zu speicherintensiv ist und keine Kopie der Elemente des Arrays erstellt wird.


9
Was istArrayUtils
Basheer AL-MOMANI

4
Arrays.asList()sollte in Ordnung sein, ArrayUtils.toObject()kopiert aber jedes Element von ain ein neues Array von Character.
EM

5
Arrays.asList(a)funktioniert nicht Sie können ( List<char>in diesem Fall) keine Liste von Grundelementen erstellen. Zuerst müssen Sie die primitiven Werte in Objekte konvertieren und deshalb ArrayUtils.toObjectwird sie verwendet.
nessa.gp

93

Sie können einfach die neue Java 8 verwenden Streams , aber Sie müssen die Arbeit mit int.

Die streamMethode der Utility-Klasse Arraysgibt Ihnen eine, IntStreamfür die Sie die minMethode verwenden können. Sie können auch tun max, sum, average, ...

Die getAsIntMethode wird verwendet, um den Wert von der zu erhaltenOptionalInt

import java.util.Arrays;

public class Test {
    public static void main(String[] args){
        int[] tab = {12, 1, 21, 8};
        int min = Arrays.stream(tab).min().getAsInt();
        int max = Arrays.stream(tab).max().getAsInt();
        System.out.println("Min = " + min);
        System.out.println("Max = " + max)
    }

}

== UPDATE ==

Wenn die Ausführungszeit wichtig ist und Sie die Daten nur einmal durchgehen möchten, können Sie die summaryStatistics()Methode wie folgt verwenden

import java.util.Arrays;
import java.util.IntSummaryStatistics;

public class SOTest {
    public static void main(String[] args){
        int[] tab = {12, 1, 21, 8};
        IntSummaryStatistics stat = Arrays.stream(tab).summaryStatistics();
        int min = stat.getMin();
        int max = stat.getMax();
        System.out.println("Min = " + min);
        System.out.println("Max = " + max);
    }
}

Dieser Ansatz kann eine bessere Leistung als die klassische Schleife liefern, da die summaryStatisticsMethode eine Reduktionsoperation ist und eine Parallelisierung ermöglicht.


57

Die Google Guava-Bibliothek verfügt über Min- und Max-Methoden in den Klassen Chars, Ints, Longs usw.

Sie können also einfach Folgendes verwenden:

Chars.min(myarray)

Es sind keine Konvertierungen erforderlich und vermutlich wird es effizient implementiert.


4
Es ist mehr oder weniger wie in der Frage implementiert, außer dass es eine IllegalArgumentException für ein Array der Länge 0 auslöst . ( Code.google.com/p/guava-libraries/source/browse/trunk/src/com/… )
ColinD

3
Dies ist die beste Lösung von allem hier. Vermeidet all diese Verwirrung zwischen java.util.Arrays # asList varargs.
Kong

20

Ja, es wird in den Sammlungen gemacht Klasse durchgeführt. Beachten Sie, dass Sie Ihr primitives Zeichenarray manuell in ein Zeichen [] konvertieren müssen.

Eine kurze Demo:

import java.util.*;

public class Main {

    public static Character[] convert(char[] chars) {
        Character[] copy = new Character[chars.length];
        for(int i = 0; i < copy.length; i++) {
            copy[i] = Character.valueOf(chars[i]);
        }
        return copy;
    }

    public static void main(String[] args) {
        char[] a = {'3', '5', '1', '4', '2'};
        Character[] b = convert(a);
        System.out.println(Collections.max(Arrays.asList(b)));
    }
}

1
Collections.min (myCollection); Wenn Sie es für Arrays verwenden möchten, können Sie dies wie Collections.min (Arrays.asList (myArray)) tun.
Zed

3
Das Konvertieren von a char []in a Character []only, um das Maximum zu bestimmen, ist ziemlich ineffizient. Erstellen Sie besser eine Dienstprogrammklasse mit statischen Methoden für jeden primitiven Typ, ähnlich wie java.util.Arrays: java.sun.com/javase/6/docs/api/java/util/Arrays.html
Christoph

@Christoph: Ja, wenn das Array groß ist, würde ich zustimmen. Die bloße Angabe, dass es "ineffizient" ist, ist nicht sinnvoll, wenn die betreffende Anwendung viele Datenbankaufrufe und / oder E / A-Operationen ausführt und die Größe des Arrays (relativ) klein ist.
Bart Kiers

Sie sollten Character.valueOf(chars[i])anstelle von new Character(chars[i])aus Leistungsgründen verwenden: java.sun.com/javase/6/docs/api/java/lang/…
Christoph

@Christoph Christoph hat recht, es ist ineffizient und dumm, ein Array für eine minimale Suche in eine Sammlung umzuwandeln.
AlexWien

16
import java.util.Arrays;

public class apples {

  public static void main(String[] args) {
    int a[] = {2,5,3,7,8};
    Arrays.sort(a);

     int min =a[0];
    System.out.println(min);
    int max= a[a.length-1];
    System.out.println(max);

  }

}

4
Bitte geben Sie eine Erklärung.
Mike Stockdale

3
Ich denke, dies bedeutet zu sagen, dass, wenn Sie das Array (in aufsteigender Reihenfolge) per Definition sortieren, der Minimalwert immer an der ersten Position, a [0], und der Maximalwert immer an der letzten Position ist , [a.length-1].
Jeff

1
Dies ist eine legitime und nützliche Methode zur Lösung des Problems. Was ist der Nachteil der Verwendung im Vergleich zu den anderen?
Alex

8
@alex Zeitkomplexität - Sortieren ist bestenfalls eine O (nlogn) -Angelegenheit, während Michael Rutherfurd-Ansatz O (n) ist.
Jajdoo

3
Wir brauchen keine Sortierung, da eine einzelne Iteration über die Liste ausreicht, um min und max zu finden.
akhil_mittal

11

Ich habe in all meinen Anwendungen eine kleine Hilfsklasse mit Methoden wie:

public static double arrayMax(double[] arr) {
    double max = Double.NEGATIVE_INFINITY;

    for(double cur: arr)
        max = Math.max(max, cur);

    return max;
}

1
Sie sollten double max = Double.NEGATIVE_INFINITY verwenden. anstelle von double max = Double.MIN_VALUE; Da MIN_VALUE für double positiv ist
krems

1
... oder Sie könnten max auf das erste Element im Array setzen und vom zweiten Element iterieren, siehe meine Antwort.
Nicholas Hamilton

3

Sie könnten es leicht mit einem IntStreamund der max()Methode tun .

Beispiel

public static int maxValue(final int[] intArray) {
  return IntStream.range(0, intArray.length).map(i -> intArray[i]).max().getAsInt();
}

Erläuterung

  1. range(0, intArray.length)- Um einen Stream mit so vielen Elementen wie möglich in der zu erhalten intArray.

  2. map(i -> intArray[i])- Ordnen Sie jedes Element des Streams einem tatsächlichen Element des Streams zu intArray.

  3. max()- Holen Sie sich das maximale Element dieses Streams als OptionalInt.

  4. getAsInt()- Packen Sie die aus OptionalInt. (Sie können auch hier verwenden : orElse(0), nur für den Fall, dass das OptionalIntleer ist.)



2
import java.util.Random;

public class Main {

public static void main(String[] args) {
   int a[] = new int [100];
   Random rnd = new Random ();

    for (int i = 0; i< a.length; i++) {
        a[i] = rnd.nextInt(99-0)+0;
        System.out.println(a[i]);
    }

    int max = 0;          

    for (int i = 0; i < a.length; i++) {
        a[i] = max;


        for (int j = i+1; j<a.length; j++) {
            if (a[j] > max) {
               max = a[j];
            }

        }
    }

    System.out.println("Max element: " + max);
}
}

2
    public int getMin(int[] values){
        int ret = values[0];
        for(int i = 1; i < values.length; i++)
            ret = Math.min(ret,values[i]);
        return ret;
    }

Dies ist für Zahlen, intaber die Frage fragt nach primitiven Wertenint, long, char, byte....
IgniteCoders

2

Eine Lösung mit reduce():

int[] array = {23, 3, 56, 97, 42};
// directly print out
Arrays.stream(array).reduce((x, y) -> x > y ? x : y).ifPresent(System.out::println);

// get the result as an int
int res = Arrays.stream(array).reduce((x, y) -> x > y ? x : y).getAsInt();
System.out.println(res);
>>
97
97

In dem obigen Code, reduce()liefert Daten in OptionalFormat, das Sie konvertieren können intdurchgetAsInt() .

Wenn wir den Maximalwert mit einer bestimmten Zahl vergleichen möchten, können wir einen Startwert festlegen in reduce():

int[] array = {23, 3, 56, 97, 42};
// e.g., compare with 100
int max = Arrays.stream(array).reduce(100, (x, y) -> x > y ? x : y);
System.out.println(max);
>>
100

Wenn im obigen Code reduce()eine Identität (Startwert) als erster Parameter verwendet wird, werden Daten im gleichen Format wie die Identität zurückgegeben. Mit dieser Eigenschaft können wir diese Lösung auf andere Arrays anwenden:

double[] array = {23.1, 3, 56.6, 97, 42};
double max = Arrays.stream(array).reduce(array[0], (x, y) -> x > y ? x : y);
System.out.println(max);
>>
97.0

1

Beispiel mit float:

public static float getMaxFloat(float[] data) {

    float[] copy = Arrays.copyOf(data, data.length);
    Arrays.sort(copy);
    return copy[data.length - 1];
}

public static float getMinFloat(float[] data) {

    float[] copy = Arrays.copyOf(data, data.length);
    Arrays.sort(copy);
    return copy[0];
}

Ihre Lösung wird zwar funktionieren, aber die Zeitkomplexität wird auf O (nlogn) erhöht, während min mithilfe anderer Antworten leicht in O (n) gefunden werden kann.
Pramod

einfach verrückt, in dieser Situation eine Sorte zu verwenden.
Nicholas Hamilton

Dies kann nützlich sein, wenn bei einigen Reparaturen der erste n> 1 kleinste / größte Wert benötigt wird.
Biziclop

1

Hier ist eine Lösung, um den Maximalwert in etwa 99% der Läufe zu erhalten (ändern Sie die 0,01, um ein besseres Ergebnis zu erzielen):

public static double getMax(double[] vals){
    final double[] max = {Double.NEGATIVE_INFINITY};

    IntStream.of(new Random().ints((int) Math.ceil(Math.log(0.01) / Math.log(1.0 - (1.0/vals.length))),0,vals.length).toArray())
            .forEach(r -> max[0] = (max[0] < vals[r])? vals[r]: max[0]);

    return max[0];
}

(Nicht ganz ernst)


;-) Das ist "nicht ganz ernst" in Ordnung. Zögern, sich zu verbessern…
Ole VV

0

Übergeben Sie das Array an eine Methode, mit der Arrays.sort()es sortiert wird, sodass nur das von der Methode verwendete Array sortiert wird, und setzen Sie dann min auf array[0]und max auf array[array.length-1].


3
Es ist wahrscheinlich erwähnenswert, dass a) dies das Array modifiziert und b) für große Arrays eine teurere Lösung O (nlog n) als O (n) ist
davidsheldon

0

Der grundlegende Weg, um den Min / Max-Wert eines Arrays zu erhalten. Wenn Sie das unsortierte Array benötigen, können Sie eine Kopie erstellen oder an eine Methode übergeben, die min oder max zurückgibt. Wenn nicht, ist das sortierte Array besser, da es in einigen Fällen schneller arbeitet.

public class MinMaxValueOfArray {
    public static void main(String[] args) {
        int[] A = {2, 4, 3, 5, 5};
        Arrays.sort(A);
        int min = A[0];
        int max = A[A.length -1];
        System.out.println("Min Value = " + min);        
        System.out.println("Max Value = " + max);
    }
}

2
Das Problem beim Sortieren besteht darin, dass für ein O (n) -Problem ein O (n log n) Overhead besteht. Dies ist jedoch besser als die anderen drei bereits gegebenen Antworten zum Sortieren des Arrays.
Teepeemm
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.