我有一个未排序的数字数组int[] anArray = { 1, 5, 2, 7 };
,我需要获取数组中最大值的值和索引,这将是 7 和 3。如何实现这个功能?
这可能不是最华丽的方式,但是能够起作用。
(必须要有 using System.Linq;
)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
.ToList()
,数组已经显式实现了IList
接口。 - millimooseIndexOf
方法,但你可以用Array.IndexOf(array,value)
代替。这是List<T>
的方法。 - sa_ddam213IList
接口,但是它们是显式实现的:http://msdn.microsoft.com/en-us/library/system.array.aspx#ExplicitInterfaceImplementationTableToggle。(数组还实现了相应的泛型 IList<T>
接口。) - millimooseToList()
的契约是始终进行复制。有时候进行复制,有时候不进行复制是一个可怕的想法 - 这将导致相当疯狂的别名错误。实际上,ToList()
的实现或多或少是 return new List(source)
。 - millimooseint[] anArray = { 1, 5, 2, 7 };
// Finding max
int m = anArray.Max();
// Positioning max
int p = Array.IndexOf(anArray, m);
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
测试用例:
var anArray = new int[] { 1, 5, 7, 4, 2 };
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
Console.WriteLine($"Maximum number = {number}, on index {index}.");
// Maximum number = 7, on index 2.
特点:
备注:
anArray.Select((n, i) => ( Index: i, Number: n)).Max()
找到的是最大索引而不是最大数字,因为元组的比较方式(item1 最重要等)的原因。 - Caius Jard如果索引没有排序,则必须至少迭代一次数组才能找到最高值。我会使用简单的for
循环:
int? maxVal = null; //nullable so this works even if you have all super-low negatives
int index = -1;
for (int i = 0; i < anArray.Length; i++)
{
int thisNum = anArray[i];
if (!maxVal.HasValue || thisNum > maxVal.Value)
{
maxVal = thisNum;
index = i;
}
}
这种方法比使用LINQ或其他一行代码的解决方案更冗长,但它可能会稍微快一点。实际上没有办法使其更快,它的时间复杂度是O(N)。
maxVal
初始化为索引为0的数组值,将 index
初始化为0,并从 i=1
开始 for 循环来节省一次迭代。 - Jon Schneider必做的 LINQ 一行代码[1]:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(相比于其他解决方案,排序可能会影响性能。)
[1]: 对于给定的"one"值。
public static void FindMax()
{
// Advantages:
// * Functional approach
// * Compact code
// Cons:
// * We are indexing into the array twice at each step
// * The Range and IEnumerable add a bit of overhead
// * Many people will find this code harder to understand
int[] array = { 1, 5, 2, 7 };
int maxIndex = Enumerable.Range(0, array.Length).Aggregate((max, i) => array[max] > array[i] ? max : i);
int maxInt = array[maxIndex];
Console.WriteLine($"Maximum int {maxInt} is found at index {maxIndex}");
}
public static void FindMax2()
{
// Advantages:
// * Near-optimal performance
int[] array = { 1, 5, 2, 7 };
int maxIndex = -1;
int maxInt = Int32.MinValue;
// Modern C# compilers optimize the case where we put array.Length in the condition
for (int i = 0; i < array.Length; i++)
{
int value = array[i];
if (value > maxInt)
{
maxInt = value;
maxIndex = i;
}
}
Console.WriteLine($"Maximum int {maxInt} is found at index {maxIndex}");
}
public static class ArrayExtensions
{
public static int MaxIndexOf<T>(this T[] input)
{
var max = input.Max();
int index = Array.IndexOf(input, max);
return index;
}
}
这适用于所有变量类型...
var array = new int[]{1, 2, 4, 10, 0, 2};
var index = array.MaxIndexOf();
var array = new double[]{1.0, 2.0, 4.0, 10.0, 0.0, 2.0};
var index = array.MaxIndexOf();
这个方法非常有效,不需要使用LINQ或其他扩展。
int[] anArray = { 1, 5, 2, 7 };
int i, mx;
int j = 0;
mx = anArray[0];
for (i = 1; i < anArray.Length; i++)
{
if (anArray[i] > mx)
{
mx = anArray[i];
j = i;
}
}
Console.Write("The largest value is: {0}, of index: {1}", mx, j);
int[] numbers = new int[7]{45,67,23,45,19,85,64};
int smallest = numbers[0];
for (int index = 0; index < numbers.Length; index++)
{
if (numbers[index] < smallest) smallest = numbers[index];
}
Console.WriteLine(smallest);
以下是下面代码的输出:
00:00:00.3279270 - max1 00:00:00.2615935 - max2 00:00:00.6010360 - max3 (arr.Max())
虽然数组中有100000000个整数,但差别并不大...
class Program
{
static void Main(string[] args)
{
int[] arr = new int[100000000];
Random randNum = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = randNum.Next(-100000000, 100000000);
}
Stopwatch stopwatch1 = new Stopwatch();
Stopwatch stopwatch2 = new Stopwatch();
Stopwatch stopwatch3 = new Stopwatch();
stopwatch1.Start();
var max = GetMaxFullIterate(arr);
Debug.WriteLine( stopwatch1.Elapsed.ToString());
stopwatch2.Start();
var max2 = GetMaxPartialIterate(arr);
Debug.WriteLine( stopwatch2.Elapsed.ToString());
stopwatch3.Start();
var max3 = arr.Max();
Debug.WriteLine(stopwatch3.Elapsed.ToString());
}
private static int GetMaxPartialIterate(int[] arr)
{
var max = arr[0];
var idx = 0;
for (int i = arr.Length / 2; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
if (arr[idx] > max)
{
max = arr[idx];
}
idx++;
}
return max;
}
private static int GetMaxFullIterate(int[] arr)
{
var max = arr[0];
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}