Entonces, 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ía 7 y 3, ¿cómo haría esto?
Entonces, 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ía 7 y 3, ¿cómo haría esto?
Respuestas:
Esta no es la forma más glamorosa, pero funciona.
(debe tener using System.Linq;
)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
.ToList()
implementación explícita de matricesIList
IList
interfaz, pero lo hacen explícitamente: msdn.microsoft.com/en-us/library/… . (Las matrices también implementan la IList<T>
interfaz genérica correspondiente .)
ToList()
es copiar siempre. Sería una idea terrible que el método a veces se copiara y otras no; esto daría lugar a errores de alias bastante locos. De hecho, la implementación de ToList()
es más o menosreturn new List(source)
Si el índice no está ordenado, debe recorrer la matriz al menos una vez para encontrar el valor más alto. Usaría un for
bucle 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 que usa LINQ u otras soluciones unifilares, pero probablemente sea un poco más rápido. Realmente no hay forma de hacer esto más rápido que O (N).
maxVal
con el valor de la matriz en el índice 0 (asumiendo que la matriz tiene al menos una longitud de 1), index
en 0 y comenzando el ciclo for en i = 1
.
El LINQ one [1] -liner obligatorio:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(La clasificación es probablemente un impacto en el rendimiento sobre las otras soluciones).
[1]: para valores dados de "uno".
Un breve resumen:
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:
Observaciones:
anArray.Select((n, i) => ( Index: i, Number: n)).Max()
encuentra el índice máximo en lugar del número máximo debido a la forma en que se comparan las tuplas (el elemento 1 es el más significativo, etc.)
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());
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, no es una gran diferencia, 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;
}
public static class ArrayExtensions
{
public static int MaxIndexOf<T>(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();
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);
}
int[] Data= { 1, 212, 333,2,12,3311,122,23 };
int large = Data.Max();
Console.WriteLine(large);
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 for
lop explícito si le importa el rendimiento.
Solo otra perspectiva usando DataTable
. Declare a DataTable
con 2 columnas llamadasindex
y val
. Agregue una AutoIncrement
opción y ambos valores AutoIncrementSeed
y a la columna. Luego use un bucle e inserte cada elemento de la matriz en una fila. Luego, usando el método, seleccione la fila que tenga el valor máximo.AutoIncrementStep
1
index
foreach
datatable
Select
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 el número más grande y el más pequeño de 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);
Si conoce el índice máximo, el acceso al valor máximo es inmediato. Entonces todo lo que necesitas es un índice máximo.
int max=0;
for(int i = 1; i < arr.Length; i++)
if (arr[i] > arr[max]) max = i;
Esta es una versión de C #. Se basa en la idea de ordenar la matriz.
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;
}
Considere lo siguiente:
/// <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;
}
Uso:
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);
Esto se puede hacer con un for
bucle sin cuerpo , si nos dirigimos hacia el golf;)
//a is the array
int mi = a.Length - 1;
for (int i=-1; ++i<a.Length-1; mi=a[mi]<a[i]?i:mi) ;
El cheque de ++i<a.Length-1
omite chequeando el último índice. No nos importa esto si lo configuramos como si el índice máximo fuera el último índice con el que comenzar. Cuando el ciclo se ejecute para los otros elementos, terminará y una cosa u otra es cierta:
mi
mi
y nos quedamos con el valor inicialmi
El trabajo real lo realizan los modificadores posteriores al ciclo:
a[mi]
es decir, la matriz indexada por mi
) que encontramos hasta ahora, menor que el elemento actual?
mi
recordandoi
,mi
(no-op)Al final de la operación, tiene el índice en el que se encuentra el máximo. Lógicamente, entonces el valor máximo esa[mi]
No pude ver cómo el "buscar el máximo y el índice de máximo" realmente necesitaba rastrear el valor máximo también, dado que si tiene una matriz y conoce el índice del valor máximo, el valor real del valor máximo es un caso trivial de usar el índice para indexar la matriz.