Menemukan nilai maks / min dalam array primitif menggunakan Java

186

Itu sepele untuk menulis fungsi untuk menentukan nilai min / maks dalam array, seperti:

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

tetapi bukankah ini sudah dilakukan di suatu tempat?

Nick Heiner
sumber
8
Array primitif ke berbagai wadah akan membantu: stackoverflow.com/questions/3770289/… diikuti oleh Collections.max(Arrays.asList()).
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Saya suka betapa bodohnya Java
Farid

Jawaban:

173

Menggunakan Commons Lang (untuk mengkonversi) + Koleksi (untuk minimum / 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));
   }
}

Catatan yang Arrays.asList()membungkus array yang mendasarinya, jadi seharusnya tidak terlalu banyak memori dan tidak boleh melakukan salinan pada elemen-elemen array.

Michael Rutherfurd
sumber
9
apa ituArrayUtils
Basheer AL-MOMANI
4
Arrays.asList()harus baik - baik saja, tetapi ArrayUtils.toObject()akan menyalin setiap elemen ake array baru Character.
EM
5
Arrays.asList(a)tidak bekerja Anda tidak dapat membuat daftar primitif ( List<char>dalam hal ini). Pertama, Anda perlu mengkonversi nilai primitif ke objek dan itulah mengapa ArrayUtils.toObjectdigunakan.
nessa.gp
96

Anda hanya dapat menggunakan baru Java 8 Streams tetapi Anda harus bekerja dengan int.

The streammetode kelas utilitas Arraysmemberi Anda IntStreamyang dapat Anda menggunakan minmetode. Anda juga dapat melakukan max, sum, average, ...

The getAsIntmetode yang digunakan untuk mendapatkan nilai dariOptionalInt

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 ==

Jika waktu eksekusi itu penting dan Anda ingin melalui data hanya sekali Anda dapat menggunakan summaryStatistics()metode seperti ini

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

Pendekatan ini dapat memberikan kinerja yang lebih baik daripada loop klasik karena summaryStatisticsmetode ini merupakan operasi reduksi dan memungkinkan paralelisasi.

Ortomala Lokni
sumber
57

The Google Jambu perpustakaan memiliki min dan metode max di Chars nya, Ints, Longs, dll kelas.

Jadi Anda cukup menggunakan:

Chars.min(myarray)

Tidak diperlukan konversi dan mungkin ini diterapkan secara efisien.

Andrew McKinlay
sumber
4
Ini diterapkan kurang lebih seperti dalam pertanyaan kecuali itu melempar IllegalArgumentException untuk array dengan panjang 0. ( code.google.com/p/guava-libraries/source/browse/trunk/src/com/… )
ColinD
3
Ini adalah solusi terbaik dari semuanya di sini. Hindari semua java.util.Arrays # asList varargs kebingungan.
Kong
20

Ya, itu dilakukan di kelas Koleksi . Perhatikan bahwa Anda perlu mengonversi array char primitif Anda ke Karakter [] secara manual.

Demo singkat:

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
sumber
1
Collections.min (myCollection); Jika Anda ingin menggunakannya untuk array, Anda dapat melakukannya seperti Collections.min (Arrays.asList (myArray));
Zed
3
mengonversi a char []menjadi Character []hanya untuk menentukan maksimum cukup tidak efisien - lebih baik buat kelas utilitas dengan metode statis untuk setiap jenis primitif yang mirip dengan java.util.Arrays: java.sun.com/javase/6/docs/api/java/util/Arrays.html
Christoph
@Christoph: ya, jika ukuran array besar, saya setuju. Cukup menyatakan itu "tidak efisien" tidak masuk akal jika aplikasi tersebut membuat banyak panggilan database dan / atau operasi I / O dan ukuran array (relatif) kecil.
Bart Kiers
Anda harus menggunakan Character.valueOf(chars[i])alih-alih new Character(chars[i])karena alasan kinerja: java.sun.com/javase/6/docs/api/java/lang/…
Christoph
@Christoph Christoph benar, tidak efisien dan bodoh untuk mengubah array ke Koleksi, untuk pencarian minimum.
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
sumber
4
Tolong berikan beberapa penjelasan.
Mike Stockdale
3
Saya pikir apa yang ingin dikatakan adalah bahwa jika Anda mengurutkan array (dalam urutan menaik), menurut definisi, nilai minimum akan selalu berada di posisi pertama, a [0], dan nilai maksimum akan selalu berada di posisi terakhir , [a.length-1].
Jeff
1
Ini adalah cara yang sah dan berguna untuk menyelesaikan masalah. Apa kerugiannya menggunakannya dibandingkan dengan yang lain?
Alex
8
Kompleksitas waktu @alex - pengurutan paling baik merupakan urusan O (nlogn), sedangkan pendekatan Michael Rutherfurd adalah O (n).
jajdoo
3
Kami tidak perlu mengurutkan sebagai iterasi tunggal dari daftar sudah cukup untuk menemukan min dan maks.
akhil_mittal
11

Saya memiliki kelas pembantu kecil di semua aplikasi saya dengan metode seperti:

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

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

    return max;
}
Sauer
sumber
1
Anda harus menggunakan double max = Double.NEGATIVE_INFINITY; bukannya double max = Double.MIN_VALUE; Karena MIN_VALUE untuk gandakan adalah positif
krem
1
... atau Anda dapat mengatur maks ke item pertama dalam array, dan beralih dari item ke-2, lihat jawaban saya.
Nicholas Hamilton
3

Anda dapat dengan mudah melakukannya dengan IntStreamdan max()metode.

Contoh

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

Penjelasan

  1. range(0, intArray.length)- Untuk mendapatkan aliran dengan elemen sebanyak yang ada di intArray.

  2. map(i -> intArray[i])- Peta setiap elemen aliran ke elemen aktual intArray.

  3. max()- Dapatkan elemen maksimum dari aliran ini sebagai OptionalInt.

  4. getAsInt()- Buka bungkusnya OptionalInt. (Anda juga bisa menggunakan di sini orElse(0):, kalau-kalau OptionalIntkosong.)

winklerrr
sumber
2

Inilah kelas utilitas yang menyediakan min/maxmetode untuk tipe primitif: Primitives.java

Christoph
sumber
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);
}
}
mark2
sumber
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
sumber
Ini untuk angka inttetapi pertanyaannya adalah meminta nilaiint, long, char, byte....
IgniteCoders
2

Solusi dengan 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

Dalam kode di atas, reduce()mengembalikan data dalam Optionalformat, yang dapat Anda konversi intolehgetAsInt() .

Jika kami ingin membandingkan nilai maks dengan angka tertentu, kami dapat menetapkan nilai awal di 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

Dalam kode di atas, ketika reduce()dengan identitas (nilai awal) sebagai parameter pertama, itu mengembalikan data dalam format yang sama dengan identitas. Dengan properti ini, kami dapat menerapkan solusi ini ke array lain:

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.
sumber
1

Contoh dengan 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];
}
Andrey
sumber
Meskipun solusi Anda akan bekerja, tetapi itu akan menambah kompleksitas waktu menjadi O (nlogn) sementara min dapat ditemukan dengan mudah di O (n) dengan menggunakan jawaban lain.
Pramod
cukup gila untuk menggunakan sejenis dalam situasi ini.
Nicholas Hamilton
Ini bisa berguna ketika n pertama> 1 nilai terkecil / terbesar diperlukan, dengan beberapa perbaikan.
biziclop
1

Berikut ini adalah solusi untuk mendapatkan nilai maksimal di sekitar 99% proses (ubah 0,01 untuk mendapatkan hasil yang lebih baik):

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

(Tidak sepenuhnya serius)

mnzl
sumber
;-) Itu "Tidak sepenuhnya serius" baik-baik saja. Ragu untuk mendukung ...
Ole VV
0

Pass array ke metode yang mengurutkannya Arrays.sort()sehingga hanya mengurutkan array metode yang digunakan kemudian set min ke array[0]dan maks ke array[array.length-1].

siapa yang diharapkan
sumber
3
Mungkin perlu dicatat bahwa a) ini memodifikasi array, dan b) untuk array besar itu solusi yang lebih mahal O (nlog n) daripada O (n)
davidsheldon
0

Cara dasar untuk mendapatkan nilai min / max Array. Jika Anda membutuhkan array yang tidak disortir, Anda dapat membuat salinan atau meneruskannya ke metode yang mengembalikan min atau maks. Jika tidak, array yang diurutkan lebih baik karena kinerjanya lebih cepat dalam beberapa kasus.

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.
sumber
2
Masalah dengan penyortiran adalah bahwa ia memiliki overhead O (n log n) untuk masalah O (n). Tapi ini lebih baik dari tiga jawaban "sort the array" lainnya yang sudah diberikan.
Teepeemm