c#に最大3つの数字を見つける方法はありますか?


99

Math.Maxに似ていますが、intの3またはparamsを取りますか?

ありがとう


3
これらの数字はどこにありますか?それらはどのように保存されますか?
コビ

回答:


141

さて、あなたはそれを2回呼び出すことができます:

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

これを頻繁に行う場合は、いつでも独自のヘルパーメソッドを作成できます...これを私のコードベースで一度見れば十分ですが、定期的ではありません。

(これは、Andrewの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
@Andrew:箇所で読んでも大丈夫だと思う。それが複数ある場合(ただし、毎回3つのパラメーターがある場合)、LINQアプローチを使用するのではなく、おそらくカスタムメソッドを記述します。MoreMath.Max(x, y, z)は、LINQのアプローチであるIMOよりも読みやすくなっています。
ジョンスキート

なぜあなたはちょうど使わなかったのpublic static int Max(params int[] values) ですか?
Navid Rahmani

2
@Navid:それを呼び出すと、Max(1, 2, 3)理由もなく配列が作成されます。比較的少数のパラメーターにいくつかのオーバーロードを提供することにより、呼び出し元の読みやすさに影響を与えることなく、より効率的にすることができます。
ジョンスキート

Math.Maxは、コードを最適化するまで一貫して優れたパフォーマンスを発揮するようです。2-> 3-> 4に進むにつれてリードが小さくなり、MoreMath.Max(x、y)を追加しても、測定可能なオーバーヘッドが発生します。Math.Max〜(1,2)43ms、(2,1)〜38ms、インライン〜(1,2)58ms、(2,1)〜53ms、委任〜(1,2)69ms、(2,1) 〜61ms。-> 3つの値の計算:〜55ms、インライン:〜62ms。-> 4つの値:〜75ms対〜80ms ...すべてが1000万回の反復と5つの測定によって行われます...最適化をオンにすると、追加する値が増えるほど、傾向が変わり、Mathが勝つようになります。しかし...パフォーマンスが重要になる前に何十億もの比較が必要になります。
イェンス2016


30

LinqにはMax関数があります。

あなたが持っているIEnumerable<int>場合はこれを直接呼び出すことができますが、これらを別々のパラメータで必要とする場合は次のような関数を作成できます:

using System.Linq;

...

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

次に、次のように呼び出すことができます:max(1, 6, 2)、任意の数のパラメーターを許可します。


2
うん、編集した回答にもあるように... Maxではなく、それを呼び出しmaxて静的にしたいのを除いて、静的にします:)少数のパラメーターでオーバーロードすることで、効率を上げることもできます。
ジョンスキート、2011

1
@ジョン・スキート:このような1つのライナーの関数を実際に作成する必要がありますか?
naveen

5
@naveen:もちろん、コードがより明確になり、複数の場所で使用している場合。何故なの?
Jon Skeet、2011

@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

何らかの理由(スペースエンジニアAPIなど)で、System.arrayにMaxの定義がない場合、またはEnumerableにアクセスできない場合、n個の値のMaxの解決策は次のとおりです。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.