Tìm giá trị tối đa / tối thiểu trong một mảng nguyên thủy bằng Java


184

Việc viết một hàm để xác định giá trị min / max trong một mảng là không quan trọng, chẳng hạn như:

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

Nhưng điều này đã không được thực hiện ở đâu đó?


8
Mảng từ nguyên thủy đến mảng container sẽ giúp: stackoverflow.com/questions/3770289/ trên tiếp theo Collections.max(Arrays.asList()).
Ciro Santilli 郝海东 冠状 病 事件 法轮功

Tôi chỉ thích Java ngu ngốc như thế nào
Farid

Câu trả lời:


172

Sử dụng Commons Lang (để chuyển đổi) + Bộ sưu tập (tối thiểu / tối đa)

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

Lưu ý rằng Arrays.asList()bao bọc mảng bên dưới, vì vậy nó không nên quá tốn bộ nhớ và nó không nên thực hiện một bản sao trên các thành phần của mảng.


9
là gìArrayUtils
Basheer AL-MOMani

4
Arrays.asList()sẽ ổn, nhưng ArrayUtils.toObject()sẽ sao chép từng phần tử của amột mảng mới Character.
EM

5
Arrays.asList(a)không hoạt động. Bạn không thể tạo một danh sách các nguyên thủy ( List<char>trong trường hợp này). Trước tiên, bạn cần chuyển đổi các giá trị nguyên thủy thành các đối tượng và đó là lý do ArrayUtils.toObjectđược sử dụng.
nessa.gp

93

Bạn có thể chỉ cần sử dụng Java 8 Streams mới nhưng bạn phải làm việc với int.

Các streamphương pháp của lớp tiện ích Arrayscung cấp cho bạn một IntStreammà bạn có thể sử dụng các minphương pháp. Bạn cũng có thể làm max, sum, average, ...

Các getAsIntphương pháp được sử dụng để nhận được giá trị từOptionalInt

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

}

== CẬP NHẬT ==

Nếu thời gian thực hiện là quan trọng và bạn chỉ muốn đi qua dữ liệu một khi bạn có thể sử dụng summaryStatistics()phương thức như thế này

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

Cách tiếp cận này có thể cho hiệu suất tốt hơn vòng lặp cổ điển vì summaryStatisticsphương thức này là một hoạt động rút gọn và nó cho phép song song hóa.


57

Các thư viện Google Ổi có min và phương pháp tối đa trong Chars của nó, Ints, Longs vv lớp.

Vì vậy, bạn có thể chỉ cần sử dụng:

Chars.min(myarray)

Không có chuyển đổi là bắt buộc và có lẽ nó được thực hiện một cách hiệu quả.


4
Nó được triển khai ít nhiều giống như trong câu hỏi ngoại trừ nó ném IllegalArgumentException cho một mảng có độ dài 0. ( code.google.com/p/guava-lologists/source/browse/trunk/src/com/ tựa )
ColinD

3
Đây là giải pháp tốt nhất của mọi thứ ở đây. Tránh tất cả những gì java.util.Arrays # asList varargs nhầm lẫn.
Kong

20

Vâng, nó được thực hiện trong lớp Bộ sưu tập . Lưu ý rằng bạn sẽ cần phải chuyển đổi mảng char nguyên thủy của mình thành Ký tự [].

Một bản demo ngắn:

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
Bộ sưu tập.min (myCollection); Nếu bạn muốn sử dụng nó cho mảng, bạn có thể làm điều đó như Collections.min (Arrays.asList (myArray));
Zed

3
chuyển đổi một char [] thành Character []chỉ để xác định mức tối đa khá kém hiệu quả - tốt hơn là tạo một lớp tiện ích với các phương thức tĩnh cho từng loại nguyên thủy tương tự như java.util.Arrays: java.sun.com/javase/6/docs/api/java/util/Arrays.html
Christoph

@Christoph: có, nếu kích thước của mảng lớn, tôi sẽ đồng ý. Nói một cách đơn giản là "không hiệu quả" sẽ không có ý nghĩa nếu ứng dụng đang được đề cập thực hiện nhiều cuộc gọi cơ sở dữ liệu và / hoặc hoạt động I / O và kích thước của mảng là (tương đối) nhỏ.
Bart Kiers

bạn nên sử dụng Character.valueOf(chars[i])thay vì vì new Character(chars[i])lý do hiệu suất: java.sun.com/javase/6/docs/api/java/lang/ mẹo
Christoph

@Christoph Christoph đã đúng, việc chuyển đổi một mảng thành Bộ sưu tập là không hiệu quả và ngu ngốc.
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
Vui lòng cung cấp một số giải thích.
Mike Stockdale

3
Tôi nghĩ điều này có nghĩa là nếu bạn sắp xếp mảng (theo thứ tự tăng dần), theo định nghĩa, giá trị tối thiểu sẽ luôn ở vị trí đầu tiên, [0] và giá trị tối đa sẽ luôn ở vị trí cuối cùng , [a.length-1].
Jeff

1
Đây là một cách hợp pháp và hữu ích để giải quyết vấn đề. Những bất lợi của việc sử dụng nó so với những người khác là gì?
Alex

8
độ phức tạp thời gian @alex - sắp xếp tốt nhất là một vấn đề O (nlogn), trong khi cách tiếp cận của Michael Rutherfurd là O (n).
jajdoo

3
Chúng tôi không cần sắp xếp như một lần lặp trong danh sách là đủ để tìm tối thiểu và tối đa.
akhil_mittal

11

Tôi có một lớp trợ giúp nhỏ trong tất cả các ứng dụng của mình với các phương thức như:

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

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

    return max;
}

1
Bạn nên sử dụng gấp đôi max = Double.NEGECT_INFINITY; thay vì gấp đôi max = Double.MIN_VALUE; Vì MIN_VALUE cho nhân đôi là tích cực
krems

1
... Hoặc bạn có thể đặt tối đa cho mục đầu tiên trong mảng và lặp lại từ mục thứ 2, xem câu trả lời của tôi.
Nicholas Hamilton

3

Bạn có thể dễ dàng làm điều đó với một IntStreammax()phương pháp.

Thí dụ

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

Giải trình

  1. range(0, intArray.length) - Để có được một luồng có nhiều yếu tố như trong intArray .

  2. map(i -> intArray[i]) - Ánh xạ mọi phần tử của luồng thành một phần tử thực tế của intArray .

  3. max() - Lấy phần tử tối đa của luồng này là OptionalInt .

  4. getAsInt()- Rút dây ra OptionalInt. (Bạn cũng có thể sử dụng ở đây : orElse(0), chỉ trong trường hợp OptionalInttrống.)



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

Đây là số intnhưng câu hỏi là yêu cầu các giá trị nguyên thủyint, long, char, byte....
IgniteCoders

2

Một giải pháp với 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

Trong đoạn mã trên, reduce()trả về dữ liệu trong Optionalđịnh dạng mà bạn có thể chuyển đổi sang intbằnggetAsInt() .

Nếu chúng ta muốn so sánh giá trị tối đa với một số nhất định, chúng ta có thể đặt giá trị bắt đầu bằng 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

Trong đoạn mã trên, khi reduce()với một danh tính (giá trị bắt đầu) làm tham số đầu tiên, nó sẽ trả về dữ liệu có cùng định dạng với danh tính. Với đặc tính này, chúng ta có thể áp dụng giải pháp này cho các mảng khác:

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

Ví dụ với 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];
}

Mặc dù giải pháp của bạn sẽ hoạt động, nhưng nó sẽ tăng độ phức tạp thời gian lên O (nlogn) trong khi min có thể được tìm thấy dễ dàng trong O (n) bằng cách sử dụng các câu trả lời khác.
Pramod

Đơn giản là điên để sử dụng một loại trong tình huống này.
Nicholas Hamilton

Nó có thể hữu ích khi cần n> 1 giá trị nhỏ nhất / lớn nhất đầu tiên, với một số sửa chữa.
biziclop

1

Đây là một giải pháp để có được giá trị tối đa trong khoảng 99% số lần chạy (thay đổi 0,01 để có kết quả tốt hơn):

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

(Không hoàn toàn nghiêm trọng)


;-) Đó không phải là hoàn toàn nghiêm trọng. Do dự để nâng cấp lên
Ole VV

0

Truyền mảng cho một phương thức sắp xếp nó Arrays.sort()để nó chỉ sắp xếp mảng mà phương thức đang sử dụng sau đó đặt min thành array[0]max thành array[array.length-1].


3
Có lẽ đáng lưu ý rằng a) điều này sửa đổi mảng và b) cho các mảng lớn, đó là một giải pháp đắt hơn O (nlog n) thay vì O (n)
davidsheldon

0

Cách cơ bản để lấy giá trị tối thiểu / tối đa của một mảng. Nếu bạn cần mảng chưa sắp xếp, bạn có thể tạo một bản sao hoặc chuyển nó sang một phương thức trả về giá trị tối thiểu hoặc tối đa. Nếu không, mảng được sắp xếp là tốt hơn vì nó thực hiện nhanh hơn trong một số trường hợp.

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
Vấn đề với việc sắp xếp là nó có một chi phí O (n log n) cho một vấn đề O (n). Nhưng điều này tốt hơn ba câu trả lời "sắp xếp mảng" khác đã được đưa ra.
Teepeemm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.