C# 用C在int数组中查找最小值#

C# 用C在int数组中查找最小值#,c#,C#,我如何在使用LINQ的c#的int arry中找到最小值: int min = theArray.Min(); 注意,如果没有任何元素,这将出错;首先检查.Length(或者,投影到int?,但这会增加开销) 如果您没有LINQ可用,那么可能: public static int Min(int[] arr) { switch (arr.Length) { case 0: throw new InvalidOperationException(); ca

我如何在使用LINQ的c#

的int arry中找到最小值:

int min = theArray.Min();
注意,如果没有任何元素,这将出错;首先检查
.Length
(或者,投影到
int?
,但这会增加开销)

如果您没有LINQ可用,那么可能:

public static int Min(int[] arr) {
    switch (arr.Length) {
        case 0: throw new InvalidOperationException();
        case 1: return arr[0];
        case 2: return Math.Min(arr[0], arr[1]);
        default:
            int min = arr[0];
            for (int i = 1; i < arr.Length; i++) {
                if (arr[i] < min) min = arr[i];
            }
            return min;
    }
}
publicstaticintmin(int[]arr){
开关(arr.Length){
案例0:抛出新的InvalidOperationException();
案例1:返回arr[0];
案例2:返回Math.Min(arr[0],arr[1]);
违约:
int min=arr[0];
对于(int i=1;i
我写了下面这篇文章来比较@Marc gravel所说的话,我告诉大家的方式在我的电脑上要快一点,而linq one是最慢的方式,而且如果你改变函数(在代码中)的位置,你总是会在使用
if
的版本时获得更好的性能

    static void Main(string[] args)
    {
        Dictionary<string, List<long>> dic = new Dictionary<string, List<long>>();

        dic["First"] = new List<long>();
        dic["Second"] = new List<long>();
        dic["Third"] = new List<long>();


        for (int i = 0; i < 500; i++)
        {
            int[] array = GetRandomArray();
            Stopwatch stopWacth = new Stopwatch();
            stopWacth.Restart();
            int n1 = FindMin(array);
            stopWacth.Stop();
            long firstTicks = stopWacth.ElapsedTicks;
            dic["First"].Add(firstTicks);

            stopWacth.Restart();
            int n2 = AnotherFindMin(array);
            stopWacth.Stop();
            long secondTick = stopWacth.ElapsedTicks;
            dic["Second"].Add(secondTick);

            stopWacth.Restart();
            int n3 = array.Min();
            stopWacth.Stop();
            long thirdTick = stopWacth.ElapsedTicks;
            dic["Third"].Add(thirdTick);

            Console.WriteLine("first tick : {0}, second tick {1}, third tick {2} ", firstTicks, secondTick, thirdTick);
        }

        Console.WriteLine("first tick : {0}, second tick {1}, third tick {2} ", dic["First"].Average(), dic["Second"].Average(), dic["Third"].Average());

        Console.ReadLine();
    }


    public static int[] GetRandomArray()
    {
        int[] retVal = new int[1000000];
        Random r = new Random();
        for (int i = 0; i < 1000000; i++)
        {
            retVal[i] = r.Next(1000000000);
        }
        return retVal;
    }

    public static int FindMin(int[] arr)
    {
        switch (arr.Length)
        {
            case 0: throw new InvalidOperationException();
            case 1: return arr[0];
            case 2: return Math.Min(arr[0], arr[1]);
            default:
                int min = arr[0];
                for (int i = 1; i < arr.Length; i++)
                {
                    if (arr[i] < min) min = arr[i];
                }
                return min;
        }
    }

    public static int AnotherFindMin(int[] arr)
    {
        if (arr.Length > 0)
        {
            int min = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < min) min = arr[i];
            }
            return min;
        }
        else
        {
            throw new InvalidOperationException();
        }
    }
}
// revised test by Marc (see comments discussion)
static class Test {
    static void Main(string[] args)
    {
        Dictionary<string, List<long>> dic = new Dictionary<string, List<long>>();

        dic["First"] = new List<long>();
        dic["Second"] = new List<long>();
        dic["Third"] = new List<long>();

        const int OUTER_LOOP = 500, INNER_LOOP = 500000;
        for (int arrSize = 1; arrSize <= 3; arrSize++)
        {
            for (int i = 0; i < OUTER_LOOP; i++)
            {
                int[] array = GetRandomArray(arrSize);
                Stopwatch stopWacth = Stopwatch.StartNew();
                for (int j = 0; j < INNER_LOOP; j++)
                {
                    int n1 = FindMin(array);
                }
                stopWacth.Stop();
                long firstTicks = stopWacth.ElapsedTicks;
                dic["First"].Add(firstTicks);

                stopWacth = Stopwatch.StartNew();
                for (int j = 0; j < INNER_LOOP; j++)
                {
                    int n2 = AnotherFindMin(array);
                }
                stopWacth.Stop();
                long secondTick = stopWacth.ElapsedTicks;
                dic["Second"].Add(secondTick);

                stopWacth = Stopwatch.StartNew();
                for (int j = 0; j < INNER_LOOP; j++)
                {
                    int n3 = array.Min();
                }
                stopWacth.Stop();
                long thirdTick = stopWacth.ElapsedTicks;
                dic["Third"].Add(thirdTick);

                //Console.WriteLine("{3}: switch : {0}, 0-check {1}, Enumerable.Min {2} ", firstTicks, secondTick, thirdTick, arrSize);
            }

            Console.WriteLine("{3}: switch : {0}, 0-check {1}, Enumerable.Min {2} ", dic["First"].Average(), dic["Second"].Average(), dic["Third"].Average(), arrSize);
        }
        Console.WriteLine("Done");
        Console.ReadLine();
    }


    public static int[] GetRandomArray(int size)
    {
        int[] retVal = new int[size];
        Random r = new Random();
        for (int i = 0; i < retVal.Length; i++)
        {
            retVal[i] = r.Next(1000000000);
        }
        return retVal;
    }

    public static int FindMin(int[] arr)
    {
        switch (arr.Length)
        {
            case 0: throw new InvalidOperationException();
            case 1: return arr[0];
            case 2: return arr[0] < arr[1] ? arr[0] : arr[1];
            default:
                int min = arr[0];
                for (int i = 1; i < arr.Length; i++)
                {
                    if (arr[i] < min) min = arr[i];
                }
                return min;
        }
    }

    public static int AnotherFindMin(int[] arr)
    {
        if (arr.Length > 0)
        {
            int min = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (arr[i] < min) min = arr[i];
            }
            return min;
        }
        else
        {
            throw new InvalidOperationException();
        }
    }
}
static void Main(字符串[]args)
{
Dictionary dic=新字典();
dic[“第一”]=新列表();
dic[“第二”]=新列表();
dic[“第三”]=新列表();
对于(int i=0;i<500;i++)
{
int[]数组=GetRandomArray();
秒表秒表=新秒表();
stopWacth.Restart();
int n1=FindMin(数组);
stopWacth.Stop();
长首刻度=止回阀。长首刻度;
dic[“第一”]。添加(第一个刻度);
stopWacth.Restart();
int n2=另一个findmin(数组);
stopWacth.Stop();
long secondTick=stopWacth.ElapsedTicks;
dic[“第二个”]。添加(第二个勾号);
stopWacth.Restart();
int n3=array.Min();
stopWacth.Stop();
长第三节=止回阀。止回阀;
dic[“第三条”]。添加(第三条);
WriteLine(“第一个记号:{0},第二个记号{1},第三个记号{2}”,第一个记号,第二个记号,第三个记号);
}
WriteLine(“第一个勾号:{0},第二个勾号{1},第三个勾号{2}”,dic[“第一”].Average(),dic[“第二”].Average(),dic[“第三”].Average());
Console.ReadLine();
}
公共静态int[]GetRandomArray()
{
int[]retVal=新int[1000000];
随机r=新随机();
对于(int i=0;i<1000000;i++)
{
retVal[i]=r.Next(100000000);
}
返回返回;
}
公共静态int FindMin(int[]arr)
{
开关(arr.Length)
{
案例0:抛出新的InvalidOperationException();
案例1:返回arr[0];
案例2:返回Math.Min(arr[0],arr[1]);
违约:
int min=arr[0];
对于(int i=1;i0)
{
int min=arr[0];
对于(int i=1;i
这是什么意思<代码>案例2:返回Math.Min(arr[0],arr[1])默认情况下你在做什么?这意味着什么<代码>案例1:返回arr[0]?@SaeedAlg-我正在检查数组的长度;如果是案例1项,则min显然是第一(唯一)项;如果有2个,那么将其视为另一个特例,因为我们可以方便地这样做-否则我们将迭代数组并找到最小值,而您对它们无能为力,您的默认值意味着您对
1
2
的数组大小执行此操作,在
case
中不需要执行此操作,您只需要一个简单的if语句,但如果您说执行此操作是为了可读性,则它是可以接受的。@Doggett-好的,按您喜欢的方式执行。老实说,过度分析?所编写的代码将运行良好,并通过我能想到的任何(正常)测试。请随意发布更简单的版本;我很乐意投它一票!但请注意我回答的第一部分
.Min()
…一次迭代中的
秒表
不会给出有意义的答案;此外,该测试只考虑
默认情况下的
情况(公平地说,这是最有可能的情况)。这个数组太大了,以至于任何测试都无法显示这个逻辑选择中的任何数字…@Marc Gravell,我已经写出了它的平均值(编辑:我的错误,这是4.0方法)也-
重新启动
-这是你的扩展方法吗?我正在(本地)用秒表替换。StartNew()@Marc gravel,我认为这并不是毫无意义的,但如果你这么认为,你有什么想法来比较它们?我得到的数组的大小是大的,所以秒表不应该是毫无意义的,在所有你的建议?不,我使用
使用System.Diagnostics
在.NET4中,重启不适合我,@MarcGravell,你应该注意程序集跳转,这对于我的方法来说更长