Пошук значення max / min у масиві примітивів за допомогою Java


185

Тривіально написати функцію для визначення значення min / max у масиві, наприклад:

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

але це вже десь не зроблено?


8
Масив примітивних для масиву контейнерів допоможе: stackoverflow.com/questions/3770289/…, далі Collections.max(Arrays.asList()).
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Мені просто подобається, наскільки явна ява
Фарід,

Відповіді:


173

Використання Commons Lang (для перетворення) + Колекції (до хв / макс)

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

Зауважте, що Arrays.asList()обертає основний масив, тому він не повинен бути занадто інтенсивним у пам’яті, і він не повинен виконувати копію на елементи масиву.


9
що такеArrayUtils
Basheer AL-MOMANI

4
Arrays.asList()має бути добре, але ArrayUtils.toObject()буде копіювати кожен елемент у aновий масив Character.
EM

5
Arrays.asList(a)не працює. Ви не можете скласти список примітивів ( List<char>у цьому випадку). Спочатку потрібно перетворити примітивні значення в об’єкти, і саме тому ArrayUtils.toObjectвоно використовується.
nessa.gp

96

Ви можете просто використовувати нову Java 8 Streams, але вам доведеться працювати int.

streamМетод класу корисності Arraysдає Вам , IntStreamна якому ви можете використовувати minметод. Ви можете також зробити max, sum, average, ...

getAsIntМетод використовується для отримання значення з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)
    }

}

== ОНОВЛЕННЯ ==

Якщо час виконання важливий і ви хочете переглядати дані лише один раз, ви можете використовувати такий summaryStatistics()метод

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

Цей підхід може дати кращі показники, ніж класичний цикл, оскільки summaryStatisticsметод є операцією зменшення і дозволяє паралелізацію.


57

Бібліотека Google Guava має методи min та max у своїх класах Chars, Ints, Longs тощо.

Тож ви можете просто використовувати:

Chars.min(myarray)

Ніяких перетворень не потрібно, і, імовірно, це ефективно здійснено.


4
Він реалізований більш-менш, як у питанні, за винятком того, що він викидає IllegalArgumentException для масиву довжиною 0. ( code.google.com/p/guava-libraries/source/browse/trunk/src/com/… )
ColinD

3
Це найкраще рішення всього тут. Уникає всієї плутанини java.util.Arrays # asList varargs.
Конг

20

Так, це робиться в Колекціях класі . Зауважте, що вам потрібно буде перетворити ваш примітивний масив char в символ [] вручну.

Коротка демонстрація:

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); Якщо ви хочете використовувати його для масивів, ви можете зробити це як Collections.min (Arrays.asList (myArray));
Зед

3
Перетворення char []до Character []тільки для визначення максимуму вельми неефективно - краще створити допоміжний клас зі статичними методами для кожного примітивного типу аналогічний java.util.Arrays: java.sun.com/javase/6/docs/api/java/util/Arrays.html
Крістоф

@Christoph: так, якщо розмір масиву великий, я погодився б. Проста заявити, що це "неефективно", не має сенсу, якщо відповідна програма робить багато дзвінків до бази даних та / або операцій вводу / виводу, а розмір масиву (відносно) малий.
Барт Кіерс

ви повинні використовувати Character.valueOf(chars[i])замість new Character(chars[i])причин продуктивності: java.sun.com/javase/6/docs/api/java/lang/…
Крістоф

@Christoph Christoph правий, неефективно і нерозумно перетворювати масив у колекцію для мінімального пошуку.
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
Будь ласка, надайте пояснення.
Майк Стокдейл

3
Я думаю, що це означає сказати, що якщо ви сортуєте масив (у порядку зростання), за визначенням мінімальне значення завжди буде на першій позиції, a [0], а максимальне значення завжди буде на останній позиції , [a.length-1].
Джефф

1
Це законний і корисний спосіб вирішення проблеми. У чому мінус його використання порівняно з іншими?
Олексій

8
Часова складність @ алекс - сортування є в кращому випадку справою O (nlogn), тоді як підхід Майкла Резерфурда - це O (n).
jajdoo

3
Нам не потрібно сортувати, оскільки однієї ітерації над списком достатньо, щоб знайти мінімум та макс.
akhil_mittal

11

У мене є маленький помічник класу у всіх моїх програмах такими методами:

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

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

    return max;
}

1
Ви повинні використовувати подвійний макс = Подвійний.NEGATIVE_INFINITY; замість подвійного max = Double.MIN_VALUE; Оскільки MIN_VALUE для подвійного є позитивним
крем

1
... або ви можете встановити max до першого елемента масиву та перейти з другого елемента, дивіться мою відповідь.
Ніколас Гамільтон

3

Ви можете легко зробити це за допомогою IntStreamі по max()методу.

Приклад

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

Пояснення

  1. range(0, intArray.length)- Щоб отримати потік з такою кількістю елементів, скільки присутніх у intArray.

  2. map(i -> intArray[i])- Зобразуйте кожен елемент потоку з фактичним елементом intArray.

  3. max()- Отримайте максимальний елемент цього потоку як OptionalInt.

  4. getAsInt()- Розгортаємо OptionalInt. (Ви також можете скористатися тут: на orElse(0)всякий випадок, якщо поле OptionalIntпорожнє.)



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

Це для чисел, intале питання задає примітивні значенняint, long, char, byte....
IgniteCoders

2

Рішення з 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

У наведеному вище коді, reduce()повертає дані в Optionalформаті, який можна перетворити в intпоgetAsInt() .

Якщо ми хочемо порівняти максимальне значення з певним числом, ми можемо встановити початкове значення в 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

У наведеному вище коді, коли reduce()з ідентифікатором (початковим значенням) є першим параметром, він повертає дані в тому ж форматі, що ідентифікатор. Маючи це властивість, ми можемо застосувати це рішення до інших масивів:

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

Приклад з поплавком:

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

Хоча ваше рішення буде працювати, але це збільшить часову складність до O (nlogn), тоді як min можна легко знайти в O (n), використовуючи інші відповіді.
Прамод

просто божевільний використовувати сорт у цій ситуації.
Ніколас Гамільтон

Це може бути корисно тоді, коли потрібен перший n> 1 найменший / найбільший показник при деяких ремонтах.
biziclop

1

Ось рішення, щоб отримати максимальне значення приблизно в 99% пробіг (змініть 0,01, щоб отримати кращий результат):

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

(Не зовсім серйозно)


;-) Це "не зовсім серйозно" в порядку. Чекаємо на виклик…
Оле VV

0

Передайте масив методу, який сортує його, Arrays.sort()щоб він лише сортував масив, який використовує метод, а потім встановлює min до array[0]та max до array[array.length-1].


3
Напевно, варто відзначити, що а) це модифікує масив, і b) для великих масивів це більш дороге рішення O (nlog n), а не O (n)
davidsheldon

0

Основний спосіб отримати значення min / max масиву. Якщо вам потрібен несортований масив, ви можете створити копію або передати її методу, який повертає min або max. Якщо ні, відсортований масив є кращим, оскільки він працює швидше в деяких випадках.

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
Проблема сортування полягає в тому, що у неї є O (n log n) накладні для O (n) проблеми. Але це краще, ніж інші три відповіді на "сортування масиву".
Teepeemm
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.