在C#中是否有一种方法可以找到三个数字的最大值?

143

这个方法应该像 Math.Max() 一样工作,但是接受三个或更多的 int 参数。


3
这些数字在哪里?它们是如何存储的? - Kobi
14个回答

233

3
我不知道你可以用[]创建一个可枚举对象。很棒。 - Mateen Ulhaq
11
@MateenUlhaq是表示new int[] { 1,2,3 }的简写形式。因此,它是由内容隐式确定类型的int数组。 - Mixxiphoid

183

好的,你可以直接调用两次:

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

如果你经常发现自己这样做,你可以编写自己的帮助方法...我很高兴在我的代码库中看到这一点一次,但不是经常性地。

(请注意,这可能比安德鲁(Andrew)基于LINQ的答案更有效率 - 但显然,你拥有的元素越多,LINQ方法就越有吸引力。)

编辑(EDIT):一个“两全其美”的方法可能是无论哪种方式,都有一套自定义的方法:

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方法更易读。 - Jon Skeet
为什么你不直接使用 public static int Max(params int[] values) - Navid Rahmani
3
因为将其称为 Max(1, 2, 3) 将无故创建一个数组。通过为相对较少的参数提供几个重载,您可以使其更加高效,而不会影响调用者的可读性。 - Jon Skeet
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 vs ~80ms...所有这些都是通过1000万次迭代和5次测量完成的...如果您打开优化,趋势将发生变化,Math 在添加更多值时获胜更多。但是...您需要进行数十亿次比较才能看到性能差异。 - Jens
这个答案对我很有用。 - Fatemeh Ghaffari

33

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:我们是否真的应该为这样的一行代码编写函数? - naveen
5
当然,如果使用它可以使代码更清晰,并且您在多个地方使用它,那么为什么不使用呢? - Jon Skeet
@Jon Skeet:感谢您的澄清。这是我长期以来一直存在的设计疑问。要还是不要 :) - naveen

14

作为通用的

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

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

7

虽然有些偏题,但这里提供中位数的计算公式,以防有人需要。

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

6

假设您有一个 List<int> intList = new List<int>{1,2,3},如果您想要获取最大值,可以执行以下操作:

int max = intList.Max();
int maxValue = intList.Max();

1
如果因为某种原因(例如:太空工程师API),System.array没有定义Max,也无法访问Enumerable,则求解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;
}

1

priceValues[]中的最大元素值为maxPriceValues:

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

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

你可以使用 if 和 else if 方法来处理三个值,但如果你像这样调用两次 Math.Max 方法会更容易:

        Console.WriteLine("Largest of three: " + Math.Max(num1, Math.Max(num2, num3)));
        Console.WriteLine("Lowest of three: " + Math.Min(num1, Math.Min(num2, num3)));

       
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接