C# 用C在int数组中查找最小值#
我如何在使用LINQ的c#的int arry中找到最小值: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
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,你应该注意程序集跳转,这对于我的方法来说更长