ใน c # มีวิธีหาจำนวนสูงสุด 3 ตัวหรือไม่?


100

ชอบ Math.Max ​​แต่ใช้ 3 หรือ params ของ int?

ขอบคุณ


3
ตัวเลขเหล่านี้อยู่ที่ไหน มีการจัดเก็บอย่างไร?
Kobi

คำตอบ:


144

คุณสามารถเรียกมันได้สองครั้ง:

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

หากคุณพบว่าตัวเองทำสิ่งนี้บ่อยครั้งคุณสามารถเขียนวิธีการช่วยเหลือของคุณเองได้เสมอ ... ฉันจะมีความสุขมากพอที่จะเห็นสิ่งนี้ในฐานรหัสของฉันเพียงครั้งเดียวแต่ไม่ใช่เป็นประจำ

(โปรดทราบว่าสิ่งนี้น่าจะมีประสิทธิภาพมากกว่าคำตอบที่ใช้ LINQ ของ Andrew แต่เห็นได้ชัดว่ายิ่งคุณมีองค์ประกอบมากเท่าไหร่แนวทาง 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
หากคุณถามคำถามเช่นนี้ประสิทธิภาพของฟังก์ชันสูงสุดมักไม่เกี่ยวข้องและความสามารถในการอ่านจะเหนือกว่า
Bas

2
@Andrew: ฉันคิดว่ามันโอเคที่จะอ่านในหนึ่งสถานที่ ถ้าฉันมีมากกว่าหนึ่งครั้ง (แต่ยังคงมี 3 พารามิเตอร์ทุกครั้ง) ฉันอาจจะเขียนวิธีการที่กำหนดเองแทนที่จะใช้วิธี LINQ MoreMath.Max(x, y, z)อ่านได้ง่ายกว่าแนวทาง LINQ, IMO
Jon Skeet

ทำไมคุณไม่ใช้เพียงpublic static int Max(params int[] values) ?
Navid Rahmani

2
@Navid: เนื่องจากการเรียกแบบนั้นMax(1, 2, 3)จะสร้างอาร์เรย์โดยไม่มีเหตุผล ด้วยการจัดเตรียมพารามิเตอร์ที่มีจำนวนมากเกินไปเล็กน้อยคุณสามารถทำให้มีประสิทธิภาพมากขึ้นโดยไม่ส่งผลต่อความสามารถในการอ่านของผู้โทร
Jon Skeet

Math.Max ​​ดูเหมือนจะทำงานได้ดีขึ้นอย่างต่อเนื่องจนกว่าคุณจะเพิ่มประสิทธิภาพโค้ดของคุณโอกาสในการขายจะลดลงเมื่อเราเปลี่ยนจาก 2 -> 3 -> 4 แม้จะเพิ่ม MoreMath ก็ตาม Max (x, y) จะมีค่าใช้จ่ายที่สามารถวัดได้ Math.Max ​​~ (1,2) 43ms, (2,1) ~ 38ms, Inline ~ (1,2) 58ms, (2,1) ~ 53ms, Delegated ~ (1,2) 69ms, (2,1) ~ 61 มิลลิวินาที -> คณิตศาสตร์ 3 ค่า: ~ 55ms, Inline: ~ 62ms -> 4 ค่า: ~ 75ms เทียบกับ ~ 80ms ... ทั้งหมดทำได้โดยการทำซ้ำ 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 มีฟังก์ชันMax

หากคุณมีIEnumerable<int>คุณสามารถเรียกสิ่งนี้ได้โดยตรง แต่ถ้าคุณต้องการสิ่งเหล่านี้ในพารามิเตอร์แยกต่างหากคุณสามารถสร้างฟังก์ชันดังนี้:

using System.Linq;

...

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

จากนั้นคุณสามารถเรียกสิ่งนี้max(1, 6, 2)ว่ามันอนุญาตให้มีพารามิเตอร์ตามจำนวนที่กำหนด


2
ใช่ตามคำตอบที่แก้ไขของฉันเช่นกัน ... ยกเว้นฉันต้องการเรียกมันMaxมากกว่าmaxและทำให้เป็นแบบคงที่ :) ด้วยการโอเวอร์โหลดพารามิเตอร์ที่น้อยลงคุณสามารถทำให้มีประสิทธิภาพมากขึ้นได้เช่นกัน
Jon Skeet

1
@ Jon Skeet: เราควรจะเขียนฟังก์ชั่นสำหรับ liners แบบนี้หรือไม่?
naveen

5
@naveen: แน่นอนว่าถ้ามันทำให้โค้ดชัดเจนขึ้นและคุณกำลังใช้มันในหลาย ๆ ที่ ทำไมจะไม่ล่ะ?
Jon Skeet

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

สิ่งนี้จะไม่ส่งคืนอะไรเลยหากตัวเลขเหมือนกัน
Zuabros

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.