C # encuentra el valor e índice de matriz más alto

Así que tengo una matriz numérica sin clasificar int[] anArray = { 1, 5, 2, 7 }; y necesito obtener tanto el valor como el índice del valor más grande en la matriz, que serían 7 y 3, ¿cómo lo haría?

Esta no es la manera más glamorosa, pero funciona.

(debe tener using System.Linq; )

  int maxValue = anArray.Max(); int maxIndex = anArray.ToList().IndexOf(maxValue); 
 int[] anArray = { 1, 5, 2, 7 }; // Finding max int m = anArray.Max(); // Positioning max int p = Array.IndexOf(anArray, m); 

Si el índice no está ordenado, debe recorrer la matriz al menos una vez para encontrar el valor más alto. Usaría un bucle for simple:

 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; } } 

Esto es más detallado que algo usando LINQ u otras soluciones de una línea, pero es probable que sea un poco más rápido. Realmente no hay forma de hacer esto más rápido que O (N).

El obligatorio LINQ one [1] -liner:

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

(La clasificación es probablemente un golpe de rendimiento sobre las otras soluciones).

[1]: Para valores dados de “uno”.

Aquí hay dos enfoques. Es posible que desee agregar manejo para cuando la matriz esté vacía.

 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}"); } 
 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); 
 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); } 

Salida para el código de abajo:

00: 00: 00.3279270 – max1 00: 00: 00.2615935 – max2 00: 00: 00.6010360 – max3 (arr.Max ())

Con 100000000 ints en matriz, la diferencia no es muy grande, pero aún así …

 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 class ArrayExtensions { public static int MaxIndexOf(this T[] input) { var max = input.Max(); int index = Array.IndexOf(input, max); return index; } } 

Esto funciona para todos los tipos de variables …

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

Considera lo siguiente:

  ///  /// Returns max value ///  /// array to search in /// index of the max value /// max value 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; } 

Uso:

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

Aquí hay una solución LINQ que es O (n) con factores constantes decentes:

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

Pero realmente debería escribir un explícito for lop si le importa el rendimiento.

Solo otra perspectiva usando DataTable . Declare una DataTable con 2 columnas llamadas index y val . Agregue una opción AutoIncrementSeed y los valores AutoIncrementSeed y AutoIncrementStep 1 a la columna de index . Luego use un ciclo foreach e inserte cada elemento de la matriz en la datatable como una fila. Luego, usando el método Select , seleccione la fila que tenga el valor máximo.

Código

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

Salida

 Max Value = 7, Index = 4 

Encuentra una demostración aquí

Un delineador de líneas sucinto

 var max = anArray.Select((n, i) => (Number: n, Index: i)).Max(); 

Caso de prueba:

 var anArray = new int[] { 1, 5, 2, 7 }; var max = anArray.Select((n, i) => (Number: n, Index: i)).Max(); Console.WriteLine($"Maximum number = {max.Number}, on index {max.Index}."); // Maximum number = 7, on index 4. 

caracteristicas:

  • Utiliza Linq (no tan optimizado como vainilla, pero el intercambio es menos código).
  • No necesita ordenar
  • Complejidad computacional: O (n).
  • Complejidad del espacio: O (n).

Encuentra el número más grande y más pequeño en la matriz:

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