C # 'da maksimum 3 sayıyı bulmanın bir yöntemi var mı?


100

Math.Max ​​gibi ama 3 veya params alıyor mu?

Teşekkürler


3
Bu numaralar nerede? Nasıl saklanır?
Kobi

Yanıtlar:


144

Peki, onu iki kez arayabilirsin:

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

Kendinizi bunu çok sık yaparken bulursanız, her zaman kendi yardımcı yönteminizi yazabilirsiniz ... Bunu kod tabanımda bir kez görmekten yeterince mutlu olurum , ancak düzenli olarak değil.

(Bunun Andrew'un LINQ temelli cevabından daha verimli olacağına dikkat edin - ancak açıkçası ne kadar çok öğeye sahipseniz LINQ yaklaşımı o kadar çekici olur.)

DÜZENLEME: "Her iki dünyanın en iyisi" yaklaşımı, her iki şekilde de özel bir yöntem setine sahip olmak olabilir:

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

Bu şekilde yazabilir MoreMath.Max(1, 2, 3)veya MoreMath.Max(1, 2, 3, 4)dizi oluşturma yükü olmadan, ama yine de yazmak MoreMath.Max(1, 2, 3, 4, 5, 6)size yükü sakıncası zaman güzel okunabilir ve tutarlı kodu.

Ben şahsen bunu LINQ yaklaşımının açık dizi yaratımından daha okunaklı buluyorum .


2
Böyle bir soru sorarsanız, maksimum işlevin performansı büyük olasılıkla ilgisizdir ve okunabilirlik üstün gelir.
Bas

2
@Andrew: Tek bir yerde okumakta sorun olmadığını düşünüyorum . Bir kereden fazla olsaydım (ama yine de her seferinde 3 parametre ile), muhtemelen LINQ yaklaşımını kullanmak yerine özel bir yöntem yazmayı tercih ederdim. MoreMath.Max(x, y, z)LINQ yaklaşımı olan IMO'dan bile daha okunabilir.
Jon Skeet

Neden sadece kullanmadın public static int Max(params int[] values) ?
Navid Rahmani

2
@Navid: Çünkü onu çağırmak sebepsiz yere Max(1, 2, 3)bir dizi yaratacaktır. Nispeten az sayıda parametre için birkaç aşırı yükleme sağlayarak, arayanın okunabilirliğini etkilemeden onu daha verimli hale getirebilirsiniz.
Jon Skeet

Math.Max, siz kodunuzu optimize edene kadar tutarlı bir şekilde daha iyi performans gösteriyor gibi görünüyor, biz 2 -> 3 -> 4'ten ilerledikçe kurşun küçülüyor, hatta MoreMath.Max ​​(x, y) eklenmesi ölçülebilir bir ek yük getiriyor. Math.Max ​​~ (1,2) 43ms, (2,1) ~ 38ms, Satır içi ~ (1,2) 58ms, (2,1) ~ 53ms, Delege ~ (1,2) 69ms, (2,1) ~ 61 ms. -> 3 değerde matematik: ~ 55ms, Satır içi: ~ 62ms. -> 4 değer: ~ 75ms - ~ 80ms ... Hepsi 10 milyon yineleme ve 5 ölçümle yapılır ... Optimizasyonları açarsanız, ne kadar çok değer eklerseniz trend değişir ve Matematik o kadar çok kazanır. Ancak ... performans önemli olmadan önce milyarlarca karşılaştırmaya ihtiyacınız olacaktır.
Jens

154

Şunları kullanabilirsiniz Enumerable.Max:

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

2
İle bir Enumerable yaratabileceğinizi bilmiyordum []. Şık.
Mateen Ulhaq

7
@MateenUlhaq bunun için kısa bir el new int[] { 1,2,3 }. Dolayısıyla, içeriği tarafından dolaylı olarak belirlenen int türünde bir dizidir.
Mixxiphoid

30

Linq'in bir Max işlevi vardır.

Eğer bir tane IEnumerable<int>varsa, bunu doğrudan çağırabilirsin, ama eğer bunları ayrı parametrelerde istiyorsan, şöyle bir fonksiyon yaratabilirsin:

using System.Linq;

...

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

O zaman buna şöyle diyebilirsiniz: max(1, 6, 2)keyfi sayıda parametreye izin verir.


2
Evet, benim düzenlenmiş cevabıma göre de ... ancak kesinlikle Maxyerine çağırmak maxve onu statik yapmak isterdim :) Daha az parametre için aşırı yükleyerek, daha verimli hale getirebilirsiniz.
Jon Skeet

1
@Jon Skeet: Bunun gibi bir gömlek için gerçekten işlevler yazmalı mıyız?
naveen

5
@naveen: Kesinlikle, eğer kodu daha net hale getiriyorsa ve onu birden çok yerde kullanıyorsanız. Neden olmasın?
Jon Skeet

@Jon Skeet: Açıkladığın için teşekkürler. Bu, uzun süredir sahip olduğum bir tasarım şüphesiydi. to or not :)
naveen

12

Jenerik olarak

public static T Min<T>(params T[] values) {
    return values.Min();
}

public static T Max<T>(params T[] values) {
    return values.Max();
}

8

konu dışı ama işte orta değerin formülü ... birisinin araması ihtimaline karşı

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}Bir maksimum değer elde etmek istiyorsanız bir sahip olduğunuzu varsayalım.

int maxValue = intList.Max();

1

Herhangi bir nedenle (örneğin Space Engineers API), System.array'in Max için bir tanımı yoksa veya Enumerable'a erişiminiz yoksa, Max of n değerleri için bir çözüm şudur:

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

Bu kodu deneyebilirsiniz:

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

Sayılar aynıysa bu hiçbir şey döndürmez.
Zuabros

0

PriceValues ​​[] içindeki maksimum öğe değeri maxPriceValues ​​şeklindedir:

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

0

Bu işlev bir dizi tamsayı alır. (@Jon Skeet'in dizi gönderme konusundaki şikayetini tamamen anlıyorum.)

Muhtemelen biraz abartılıdır.

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

Ardından işlevi çağırın:

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

// highest_val = 72727275
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.