115

所以我有一个未排序的数字数组int[] anArray = { 1, 5, 2, 7 };,我需要获取数组中最大值的值和索引,即 7 和 3,我该怎么做?

4

20 回答 20

175

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

(必须有using System.Linq;

 int maxValue = anArray.Max();
 int maxIndex = anArray.ToList().IndexOf(maxValue);
于 2012-12-07T00:23:39.810 回答
49
int[] anArray = { 1, 5, 2, 7 };
// Finding max
int m = anArray.Max();

// Positioning max
int p = Array.IndexOf(anArray, m);
于 2012-12-07T00:27:58.083 回答
30

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

于 2012-12-07T00:23:47.377 回答
25

简洁的单行:

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.

特征:

  • 使用 Linq(不如 vanilla 优化,但代价是代码更少)。
  • 不需要排序。
  • 计算复杂度:O(n)。
  • 空间复杂度:O(n)。

评论:

  • 确保数字(而不是索引)是元组中的第一个元素,因为元组排序是通过从左到右比较元组项来完成的。
于 2018-05-08T18:17:30.397 回答
14

强制性 LINQ one [1] -liner:

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

(排序可能是对其他解决方案的性能打击。)

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

于 2012-12-07T00:27:03.843 回答
3

这里有两种方法。当数组为空时,您可能需要添加处理。

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}");
}
于 2016-04-02T14:15:11.560 回答
2
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);
于 2014-05-09T12:22:25.573 回答
2
 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();
于 2016-06-02T15:27:01.723 回答
1
anArray.Select((n, i) => new { Value = n, Index = i })
    .Where(s => s.Value == anArray.Max());
于 2012-12-07T00:28:12.190 回答
1

波纹管代码的输出:

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;
        }
于 2014-12-04T04:10:14.883 回答
1
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);
}
于 2017-11-12T10:59:24.340 回答
0
int[] Data= { 1, 212, 333,2,12,3311,122,23 };
int large = Data.Max();
Console.WriteLine(large);
于 2015-05-04T17:19:47.143 回答
0

考虑以下:

    /// <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);
于 2016-08-12T01:06:42.423 回答
0

这是一个 O(n) 的 LINQ 解决方案,具有不错的常数因子:

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但是如果你关心性能,你真的应该写一个明确的lop。

于 2016-09-04T14:39:25.223 回答
0

只是另一个使用DataTable. DataTable用 2 列声明 aindexval。在列中添加一个AutoIncrement选项以及两者AutoIncrementSeedAutoIncrementStep值。然后使用循环并将每个数组项作为一行插入。然后通过使用方法,选择具有最大值的行。1indexforeachdatatableSelect

代码

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

在此处查找演示

于 2018-02-13T06:35:57.310 回答
0

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

int max=0;

for(int i = 1; i < arr.Length; i++)
    if (arr[i] > arr[max]) max = i;
于 2019-03-30T13:00:20.760 回答
0

这是一个 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;
}

于 2019-08-03T10:58:45.253 回答
0

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省略检查最后一个索引的检查。如果我们将其设置为好像最大索引是开始的最后一个索引,我们不介意这一点。当循环针对其他元素运行时,它将完成并且其中一件事或另一件事是正确的:

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

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

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

在操作结束时,您将获得要找到最大值的索引。从逻辑上讲,最大值是a[mi]

如果你有一个数组,并且你知道最大值的索引,最大值的实际值,我也不太明白“查找最大值和最大值的索引”是如何真正需要跟踪最大值的是使用索引来索引数组的一个小例子。

于 2020-08-26T20:59:40.663 回答
0

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

  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 }

享受!:-)

于 2020-11-19T20:25:58.367 回答
-1

找出数组中最大和最小的数:

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);
于 2018-06-03T21:55:58.717 回答