C # 查找最高的数组值和索引

我有一个未排序的数值数组 int[] anArray = { 1, 5, 2, 7 };我需要得到数组中最大值的值和索引它们分别是7和3我该怎么做呢?

429702 次浏览

这不是最迷人的方式,但却很有效。

(必须有 using System.Linq;)

 int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);

如果索引未排序,则必须至少迭代数组一次才能找到最高值。我会使用一个简单的 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)更快了。

The obligatory LINQ one[1]-liner:

var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();

(与其他解决方案相比,排序可能对性能造成了影响。)

[1] : 对于给定的“ one”值。

int[] anArray = { 1, 5, 2, 7 };
// Finding max
int m = anArray.Max();


// Positioning max
int p = Array.IndexOf(anArray, m);
anArray.Select((n, i) => new { Value = n, Index = i })
.Where(s => s.Value == anArray.Max());
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);

Output for bellow code:

我不知道,我不知道,我不知道,我不知道 我不知道,我不知道,我不知道,我不知道 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;
}
int[] Data= { 1, 212, 333,2,12,3311,122,23 };
int large = Data.Max();
Console.WriteLine(large);

这里有两种方法。您可能希望添加数组为空时的处理。

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();

考虑以下几点:

    /// <summary>
/// Returns max value
/// </summary>
/// <param name="arr">array to search in</param>
/// <param name="index">index of the max value</param>
/// <returns>max value</returns>
public static int MaxAt(int[] arr, out int index)
{
index = -1;
int max = Int32.MinValue;


for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
index = i;
}
}


return max;
}

用法:

int m, at;
m = MaxAt(new int[]{1,2,7,3,4,5,6}, out at);
Console.WriteLine("Max: {0}, found at: {1}", m, at);

这里有一个 LINQ 解,它是 O (n) ,具有良好的常数因子:

int[] anArray = { 1, 5, 2, 7, 1 };


int index = 0;
int maxIndex = 0;


var max = anArray.Aggregate(
(oldMax, element) => {
++index;
if (element <= oldMax)
return oldMax;
maxIndex = index;
return element;
}
);


Console.WriteLine("max = {0}, maxIndex = {1}", max, maxIndex);

但是,如果您关心性能,那么应该编写一个明确的 for代码。

public static void Main()
{
int a,b=0;
int []arr={1, 2, 2, 3, 3, 4, 5, 6, 5, 7, 7, 7, 100, 8, 1};


for(int i=arr.Length-1 ; i>-1 ; i--)
{
a = arr[i];


if(a > b)
{
b=a;
}
}
Console.WriteLine(b);
}

只是使用 DataTable的另一个透视图。声明一个包含两列的 DataTable,称为 indexval。在 index列中添加一个 AutoIncrement选项和 AutoIncrementSeedAutoIncrementStep1。然后使用 foreach循环并将每个数组项作为一行插入到 DataTable0中。然后使用 DataTable1方法,选择具有最大值的行。

密码

int[] anArray = { 1, 5, 2, 7 };
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[2] { new DataColumn("index"), new DataColumn("val")});
dt.Columns["index"].AutoIncrement = true;
dt.Columns["index"].AutoIncrementSeed = 1;
dt.Columns["index"].AutoIncrementStep = 1;
foreach(int i in anArray)
dt.Rows.Add(null, i);


DataRow[] dr = dt.Select("[val] = MAX([val])");
Console.WriteLine("Max Value = {0}, Index = {1}", dr[0][1], dr[0][0]);

输出

Max Value = 7, Index = 4

在这里找到一个演示

一句简洁的俏皮话:

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.

Features:

  • 使用 Linq (不像香草那样优化,但代码更少)。
  • 不需要排序。
  • 计算复杂度: O (n)。
  • 空间复杂度: O (n)。

备注:

  • 确保数字(而不是索引)是元组中的第一个元素,因为元组排序是通过从左到右比较元组项来完成的。

查找数组中最大和最小的数字:

int[] arr = new int[] {35,28,20,89,63,45,12};
int big = 0;
int little = 0;


for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);


if (arr[i] > arr[0])
{
big = arr[i];
}
else
{
little = arr[i];


}
}


Console.WriteLine("most big number inside of array is " + big);
Console.WriteLine("most little number inside of array is " + little);

如果你知道最大索引访问的最大值是即时的。所以你需要的是最大索引。

int max=0;


for(int i = 1; i < arr.Length; i++)
if (arr[i] > arr[max]) max = i;

这是一个 C # 版本,它基于数组排序的思想。

public int solution(int[] A)
{
// write your code in C# 6.0 with .NET 4.5 (Mono)
Array.Sort(A);
var max = A.Max();
if(max < 0)
return 1;
else
for (int i = 1; i < max; i++)
{
if(!A.Contains(i)) {
return i;
}
}
return max + 1;
}


如果我们要去打高尔夫,这可以用无身 for循环来完成;)

//a is the array




int mi = a.Length - 1;
for (int i=-1; ++i<a.Length-1; mi=a[mi]<a[i]?i:mi) ;

++i<a.Length-1检查省略了检查最后一个索引。如果我们将 max 索引设置为最后一个开始的索引,我们不会介意这一点。.当循环为其他元素运行时,它将结束,其中一个元素为真:

  • 我们发现一个新的最大值,因此一个新的最大索引 mi
  • 最后一个索引一直是最大值,所以我们没有找到一个新的 mi,我们坚持使用初始的 mi

真正的工作是由后循环修饰符完成的:

  • 到目前为止我们发现的最大值(a[mi],即由 mi索引的数组)是否小于当前项目?
    • 是的,然后通过记住 i来存储一个新的 mi,
    • 然后存储现有的 mi(no-op)

在操作结束时,您可以找到最大值所在的索引。逻辑上,最大值是 a[mi]

我不太明白“ find max and index of max”如何真正需要跟踪 max 值,因为如果你有一个数组,并且你知道 max 值的索引,那么 max 值的实际值只是使用 index 来索引数组的一个小例子。.

这个长长的列表中的另一个答案,但是我认为它是值得的,因为它提供了一些大多数(或全部?)的好处其他答案则不然:

  1. 下面的方法只在集合中循环一次,因此顺序是 O (N)
  2. 该方法查找最大值的 所有索引
  3. 该方法可用于寻找 任何比较的指数: minmaxequalsnot equals等。
  4. 该方法可以通过 LINQ 选择器实现 观察物体

方法:

///-------------------------------------------------------------------
/// <summary>
/// Get the indices of all values that meet the condition that is defined by the comparer.
/// </summary>
/// <typeparam name="TSource">The type of the values in the source collection.</typeparam>
/// <typeparam name="TCompare">The type of the values that are compared.</typeparam>
/// <param name="i_collection">The collection of values that is analysed.</param>
/// <param name="i_selector">The selector to retrieve the compare-values from the source-values.</param>
/// <param name="i_comparer">The comparer that is used to compare the values of the collection.</param>
/// <returns>The indices of all values that meet the condition that is defined by the comparer.</returns>
/// Create <see cref="IComparer{T}"/> from comparison function:
///   Comparer{T}.Create ( comparison )
/// Comparison examples:
/// - max:      (a, b) => a.CompareTo (b)
/// - min:      (a, b) => -(a.CompareTo (b))
/// - == x:     (a, b) => a == 4 ? 0 : -1
/// - != x:     (a, b) => a != 4 ? 0 : -1
///-------------------------------------------------------------------
public static IEnumerable<int> GetIndices<TSource, TCompare> (this IEnumerable<TSource> i_collection,
Func<TSource, TCompare> i_selector,
IComparer<TCompare> i_comparer)
{
if (i_collection == null)
throw new ArgumentNullException (nameof (i_collection));
if (!i_collection.Any ())
return new int[0];


int index = 0;
var indices = new List<int> ();
TCompare reference = i_selector (i_collection.First ());


foreach (var value in i_collection)
{
var compare = i_selector (value);
int result = i_comparer.Compare (compare, reference);
if (result > 0)
{
reference = compare;
indices.Clear ();
indices.Add (index);
}
else if (result == 0)
indices.Add (index);


index++;
}


return indices;
}

如果不需要选择器,那么将方法更改为

public static IEnumerable<int> GetIndices<TCompare> (this IEnumerable<TCompare> i_collection,
IComparer<TCompare> i_comparer)

并消除所有 i_selector的出现。

概念证明:

//########## test #1: int array ##########
int[] test = { 1, 5, 4, 9, 2, 7, 4, 6, 5, 9, 4 };


// get indices of maximum:
var indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a.CompareTo (b)));
// indices: { 3, 9 }


// get indices of all '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 4 ? 0 : -1));
// indices: { 2, 6, 10 }


// get indices of all except '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a != 4 ? 0 : -1));
// indices: { 0, 1, 3, 4, 5, 7, 8, 9 }


// get indices of all '15':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 15 ? 0 : -1));
// indices: { }


//########## test #2: named tuple array ##########
var datas = new (object anything, double score)[]
{
(999,               0.1),
(new object (),     0.42),
("hello",           0.3),
(new Exception (),  0.16),
("abcde",           0.42)
};
// get indices of highest score:
indices = datas.GetIndices (data => data.score, Comparer<double>.Create ((a, b) => a.CompareTo (b)));
// indices: { 1, 4 }

享受吧! : -)

旧文章,但这是超级简单的列表:

For Maximum:

 List<int> lst = new List<int>(YourArray);
int Max = lst.OrderByDescending(x => x).First();

至少:

List<int> lst = new List<int>(YourArray);
int Max = lst.OrderBy(x => x).First();

当然,您可以用任何数值变量类型(浮点数、十进制等)替换“ int”数据类型。

这是非常高性能的 BTW 和击败任何其他方法(IMHO)

这就像一个魅力,不需要 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);