В с # есть способ найти максимум 3 числа?


99

Как Math.Max, но принимает 3 или параметры int?

Спасибо


3
Где эти числа? Как они хранятся?
— Kobi

Ответы:


142

Ну, вы можете просто позвонить дважды:

int max3 = Math.Max(x, Math.Max(y, z));

Если вы обнаружите, что делаете это часто, вы всегда можете написать свой собственный вспомогательный метод ... Я был бы достаточно счастлив увидеть это в своей базе кода один раз , но не регулярно.

(Обратите внимание, что это, вероятно, будет более эффективным, чем ответ Эндрю на основе LINQ, но, очевидно, чем больше у вас элементов, тем привлекательнее подход LINQ.)

РЕДАКТИРОВАТЬ: подход "лучшее из обоих миров" может заключаться в том, чтобы иметь собственный набор методов в любом случае:

public static class MoreMath
{
    // This method only exists for consistency, so you can *always* call
    // MoreMath.Max instead of alternating between MoreMath.Max and Math.Max
    // depending on your argument count.
    public static int Max(int x, int y)
    {
        return Math.Max(x, y);
    }

    public static int Max(int x, int y, int z)
    {
        // Or inline it as x < y ? (y < z ? z : y) : (x < z ? z : x);
        // Time it before micro-optimizing though!
        return Math.Max(x, Math.Max(y, z));
    }

    public static int Max(int w, int x, int y, int z)
    {
        return Math.Max(w, Math.Max(x, Math.Max(y, z)));
    }

    public static int Max(params int[] values)
    {
        return Enumerable.Max(values);
    }
}

Таким образом, вы можете писать MoreMath.Max(1, 2, 3)или MoreMath.Max(1, 2, 3, 4)без накладных расходов на создание массива, но по-прежнему писать MoreMath.Max(1, 2, 3, 4, 5, 6)для приятного читаемого и последовательного кода, когда вы не возражаете против накладных расходов.

Я лично считаю это более читаемым, чем явное создание массива в рамках подхода LINQ.


2
Если вы зададите такой вопрос, производительность функции max, скорее всего, не имеет значения, а удобочитаемость будет преобладать.
— Bas

2
@ Андрей: Я думаю, что читать в одном месте - это нормально . Если бы он у меня был более одного раза (но по-прежнему с 3 параметрами каждый раз), я бы, вероятно, предпочел написать собственный метод, чем использовать подход LINQ. MoreMath.Max(x, y, z)даже более читабелен, чем подход LINQ, ИМО.
— Джон Скит

Почему вы не использовали всего public static int Max(params int[] values) ?
— Навид Рахмани

2
@Navid: Потому что это называется Max(1, 2, 3) создаст массив без причины. Предоставляя несколько перегрузок для относительно небольшого количества параметров, вы можете сделать его более эффективным, не влияя на удобочитаемость вызывающего.
— Джон Скит

Math.Max, кажется, стабильно работает лучше, пока вы не оптимизируете свой код, он сокращается при переходе от 2 -> 3 -> 4, даже добавление MoreMath.Max ​​(x, y) влечет за собой измеримые накладные расходы. Math.Max ​​~ (1,2) 43 мс, (2,1) ~ 38 мс, встроенный ~ (1,2) 58 мс, (2,1) ~ 53 мс, делегированный ~ (1,2) 69 мс, (2,1) ~ 61 мс. -> Математика по 3 значениям: ~ 55 мс, встроенная: ~ 62 мс. -> 4 значения: ~ 75 мс против ~ 80 мс ... Все сделано за 10 миллионов итераций и 5 измерений ... Если вы включите оптимизацию, тенденция изменится, и математика будет выигрывать больше, чем больше значений вы добавляете. Но ... вам потребуются миллиарды сравнений, прежде чем производительность будет иметь значение.
— Jens

154

Вы можете использовать Enumerable.Max:

new [] { 1, 2, 3 }.Max();

2
Я не знал, что вы можете создать Enumerable с помощью []. Отлично.
— Mateen Ulhaq

7
@MateenUlhaq - это короткая рука new int[] { 1,2,3 }. Итак, это массив типа int, который неявно определяется его содержимым.
— Mixxiphoid

30

У Linq есть Макс .

Если у вас есть, IEnumerable<int>вы можете вызвать это напрямую, но если вам нужны отдельные параметры, вы можете создать такую ​​функцию:

using System.Linq;

...

static int Max(params int[] numbers)
{
    return numbers.Max();
}

Тогда вы могли бы назвать его так:, max(1, 6, 2)он допускает произвольное количество параметров.


2
Да, в соответствии с моим отредактированным ответом ... за исключением того, что я определенно хотел бы назвать его, Maxа не maxи сделать его статическим :) Перегрузив его для меньшего количества параметров, вы также можете сделать его более эффективным.
— Джон Скит

1
@Jon Skeet: стоит ли нам писать такие функции для однострочников?
— naveen

5
@naveen: Безусловно, если это сделает код более понятным, и вы используете его в нескольких местах. Почему нет?
— Джон Скит

@Jon Skeet: спасибо за разъяснения. это было дизайнерское сомнение, которое у меня было долгое время. делать или не делать :)
— naveen


8

не по теме, но вот формула среднего значения .. на всякий случай, если кто-то его ищет

Math.Min(Math.Min(Math.Max(x,y), Math.Max(y,z)), Math.Max(x,z));

3

Предположим, у вас есть, List<int> intList = new List<int>{1,2,3}если вы хотите получить максимальное значение, которое вы могли бы сделать

int maxValue = intList.Max();

1

Если по какой-либо причине (например, Space Engineers API) System.array не имеет определения Max и у вас нет доступа к Enumerable, решение для Max из n значений:

public int Max(int[] values) {
    if(values.Length < 1) {
        return 0;
    }
    if(values.Length < 2) {
        return values[0];
    }
    if(values.Length < 3) {
       return Math.Max(values[0], values[1]); 
    }
    int runningMax = values[0];
    for(int i=1; i<values.Length - 1; i++) {
       runningMax = Math.Max(runningMax, values[i]);
    }
    return runningMax;
}

0

Вы можете попробовать этот код:

private float GetBrightestColor(float r, float g, float b) { 
    if (r > g && r > b) {
        return r;
    } else if (g > r && g > b) { 
        return g;
    } else if (b > r && b > g) { 
        return b;
    }
}

Это ничего не вернет, если числа совпадают.
— Зуаброс,

0

Максимальное значение элемента в priceValues ​​[] - maxPriceValues:

double[] priceValues = new double[3];
priceValues [0] = 1;
priceValues [1] = 2;
priceValues [2] = 3;
double maxPriceValues = priceValues.Max();

0

Эта функция принимает массив целых чисел. (Я полностью понимаю жалобу @Jon Skeet на отправку массивов.)

Наверное, это перебор.

    public static int GetMax(int[] array) // must be a array of ints
    {
        int current_greatest_value = array[0]; // initializes it

        for (int i = 1; i <= array.Length; i++)
        {
            // compare current number against next number

            if (i+1 <= array.Length-1) // prevent "index outside bounds of array" error below with array[i+1]
            {
                // array[i+1] exists
                if (array[i] < array[i+1] || array[i] <= current_greatest_value)
                {
                    // current val is less than next, and less than the current greatest val, so go to next iteration
                    continue;
                }
            } else
            {
                // array[i+1] doesn't exist, we are at the last element
                if (array[i] > current_greatest_value)
                {
                    // current iteration val is greater than current_greatest_value
                    current_greatest_value = array[i];
                }
                break; // next for loop i index will be invalid
            }

            // if it gets here, current val is greater than next, so for now assign that value to greatest_value
            current_greatest_value = array[i];
        }

        return current_greatest_value;
    }

Затем вызовите функцию:

int highest_val = GetMax (new[] { 1,6,2,72727275,2323});

// highest_val = 72727275
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.