Znajdowanie wartości maksymalnej / minimalnej w tablicy operacji podstawowych za pomocą Java

185

Pisanie funkcji określającej wartość min / max w tablicy jest trywialne, na przykład:

/**
 * 
 * @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;
}

ale czy to już gdzieś nie zostało zrobione?

Nick Heiner
źródło
8
Tablica prymitywnych do tablicy kontenerów pomogłaby: stackoverflow.com/questions/3770289/... a następnie Collections.max(Arrays.asList()).
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
Uwielbiam, jak głupia jest Jawa
Farid

Odpowiedzi:

173

Korzystanie z Commons Lang (do konwersji) + Kolekcje (do min / maks)

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));
   }
}

Zauważ, że Arrays.asList()otacza podstawową tablicę, więc nie powinna być zbyt obciążająca pamięć i nie powinna wykonywać kopii na elementach tablicy.

Michael Rutherfurd
źródło
9
co to jestArrayUtils
Basheer AL-MOMANI
4
Arrays.asList()powinno być w porządku, ale ArrayUtils.toObject()skopiuje każdy element ado nowej tablicy Character.
EM
5
Arrays.asList(a)nie działa Nie możesz zrobić listy prymitywów ( List<char>w tym przypadku). Najpierw musisz przekonwertować pierwotne wartości na obiekty i dlatego ArrayUtils.toObjectjest używany.
nessa.gp
96

Można po prostu skorzystać z nowych Java 8 Streams , ale trzeba pracować z int.

streamMetoda klasie użytkowej Arraysdaje IntStreamna których można użyć minmetody. Można również zrobić max, sum, average, ...

Ta getAsIntmetoda służy do uzyskania wartości zOptionalInt

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)
    }

}

== AKTUALIZACJA ==

Jeśli czas wykonania jest ważny i chcesz przejrzeć dane tylko raz, możesz użyć takiej summaryStatistics()metody

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);
    }
}

Takie podejście może dać lepszą wydajność niż klasyczna pętla, ponieważ summaryStatisticsmetoda jest operacją redukcji i umożliwia równoległość.

Ortomala Lokni
źródło
57

Biblioteka Google Guava ma metody min i max w swoich klasach Chars, Ints, Longs itp.

Możesz więc po prostu użyć:

Chars.min(myarray)

Nie są wymagane żadne konwersje i prawdopodobnie jest to skutecznie wdrożone.

Andrew McKinlay
źródło
4
Jest zaimplementowany mniej więcej tak jak w pytaniu, z wyjątkiem tego, że zgłasza IllegalArgumentException dla tablicy o długości 0. ( code.google.com/p/guava-libraries/source/browse/trunk/src/com/… )
ColinD
3
To najlepsze rozwiązanie wszystkiego tutaj. Unika całego zamieszania java.util.Arrays # asList varargs.
Kong
20

Tak, odbywa się to w klasie Kolekcje . Zauważ, że będziesz musiał ręcznie przekonwertować pierwotną tablicę znaków na znak [].

Krótkie 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)));
    }
}
Bart Kiers
źródło
1
Collections.min (myCollection); Jeśli chcesz używać go do tablic, możesz to zrobić podobnie jak Collections.min (Arrays.asList (myArray));
Zed
3
konwersja a char []na Character []jedyną w celu ustalenia maksimum jest dość nieefektywna - lepiej utwórz klasę narzędziową z metodami statycznymi dla każdego typu pierwotnego podobnego do java.util.Arrays: java.sun.com/javase/6/docs/api/java/util/Arrays.html
Christoph
@Christoph: tak, jeśli rozmiar tablicy jest duży, zgodziłbym się. Samo stwierdzenie, że jest „nieefektywne”, nie ma sensu, jeśli dana aplikacja wykonuje wiele wywołań bazy danych i / lub operacji We / Wy, a rozmiar tablicy jest (względnie) mały.
Bart Kiers
powinieneś używać Character.valueOf(chars[i])zamiast ze względu new Character(chars[i])na wydajność: java.sun.com/javase/6/docs/api/java/lang/…
Christoph
@Christoph Christoph ma rację, nieefektywne i głupie jest przekształcanie tablicy w kolekcję w celu wyszukiwania min. Maks.
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);

  }

}
Lubna_Nsour
źródło
4
Proszę podać wyjaśnienie.
Mike Stockdale,
3
Myślę, że oznacza to, że jeśli posortujesz tablicę (w porządku rosnącym), z definicji minimalna wartość zawsze będzie na pierwszej pozycji, a [0], a maksymalna będzie zawsze na ostatniej pozycji , [a.length-1].
Jeff
1
Jest to uzasadniony i użyteczny sposób rozwiązania problemu. Jaka jest wada korzystania z niego w porównaniu do innych?
Alex
8
Złożoność czasu @alex - sortowanie jest co najwyżej sprawą O (nlogn), podczas gdy podejście Michaela Rutherfurda to O (n).
jajdoo
3
Nie potrzebujemy sortowania, ponieważ pojedyncza iteracja po liście wystarczy, aby znaleźć min i max.
akhil_mittal
11

Mam małą klasę pomocników we wszystkich moich aplikacjach z metodami takimi jak:

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

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

    return max;
}
Sauer
źródło
1
Powinieneś użyć double max = Double.NEGATIVE_INFINITY; zamiast podwójnego max = Double.MIN_VALUE; Ponieważ MIN_VALUE dla podwójnego jest dodatnie
krems
1
... lub możesz ustawić maks. na pierwszy element w tablicy i iterować od 2. elementu, zobacz moją odpowiedź.
Nicholas Hamilton
3

Można łatwo zrobić ze związkiem IntStreami tym max()sposobem.

Przykład

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

Wyjaśnienie

  1. range(0, intArray.length)- Aby uzyskać strumień z tyloma elementami, ile jest obecnych w intArray.

  2. map(i -> intArray[i])- Mapuj każdy element strumienia do rzeczywistego elementu intArray.

  3. max()- Uzyskaj maksymalny element tego strumienia jako OptionalInt.

  4. getAsInt()- Rozpakuj OptionalInt. (Możesz także użyć tutaj: orElse(0)na wypadek, gdyby OptionalIntbył pusty.)

winklerrr
źródło
2

Oto klasa narzędzi zapewniająca min/maxmetody dla typów pierwotnych: Primitive.java

Christoph
źródło
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);
}
}
ocena 2
źródło
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;
    }
Nicholas Hamilton
źródło
Dotyczy to liczb, intale pytanie dotyczy prymitywnych wartościint, long, char, byte....
IgniteCoders
2

Rozwiązanie z 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

W powyższym kodzie, reduce()zwraca dane w Optionalformacie, który można przekonwertować do into getAsInt().

Jeśli chcemy porównać wartość maksymalną z określoną liczbą, możemy ustawić wartość początkową w 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

W powyższym kodzie, gdy reduce()z tożsamością (wartością początkową) jako pierwszym parametrem, zwraca dane w tym samym formacie z tożsamością. Dzięki tej właściwości możemy zastosować to rozwiązanie do innych tablic:

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
Simon Z.
źródło
1

Przykład z pływakiem:

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];
}
Andrey
źródło
Chociaż twoje rozwiązanie będzie działać, ale zwiększy złożoność czasu do O (nlogn), podczas gdy min można łatwo znaleźć w O (n) przy użyciu innych odpowiedzi.
Pramod
po prostu szalony, aby użyć czegoś w tej sytuacji.
Nicholas Hamilton
Może być przydatny, gdy potrzebna jest pierwsza n> 1 najmniejsza / największa wartość, z pewnymi naprawami.
biziclop
1

Oto rozwiązanie, aby uzyskać maksymalną wartość w około 99% przebiegów (zmień 0,01, aby uzyskać lepszy wynik):

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];
}

(Nie do końca poważny)

mnzl
źródło
;-) To „Nie całkiem poważne”, w porządku. Wahając się, by głosować…
Ole VV,
0

Przepuścić tablicę do metody, która z rodzaju IT Arrays.sort()więc tylko sortowanie tablicy sposób używa ustawia min do array[0]i maksymalnie do array[array.length-1].

whoduexpect
źródło
3
Prawdopodobnie warto zauważyć, że a) to modyfikuje tablicę, oraz b) w przypadku dużych tablic jest to droższe rozwiązanie O (nlog n) niż O (n)
davidsheldon 30.08.16
0

Podstawowy sposób uzyskania wartości min / max tablicy. Jeśli potrzebujesz nieposortowanej tablicy, możesz utworzyć kopię lub przekazać ją do metody, która zwraca min lub max. Jeśli nie, posortowana tablica jest lepsza, ponieważ w niektórych przypadkach działa szybciej.

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);
    }
}
Kim G.
źródło
2
Problem z sortowaniem polega na tym, że ma on narzut O (n log n) dla problemu O (n). Ale to jest lepsze niż trzy pozostałe odpowiedzi „sortuj tablicę” już podane.
Teepeemm,