Ich habe also ein unsortiertes numerisches Array int[] anArray = { 1, 5, 2, 7 };
und muss sowohl den Wert als auch den Index des größten Werts im Array abrufen, der 7 und 3 wäre. Wie würde ich das tun?
Ich habe also ein unsortiertes numerisches Array int[] anArray = { 1, 5, 2, 7 };
und muss sowohl den Wert als auch den Index des größten Werts im Array abrufen, der 7 und 3 wäre. Wie würde ich das tun?
Antworten:
Dies ist nicht der glamouröseste Weg, sondern funktioniert.
(muss haben using System.Linq;
)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
.ToList()
Arrays explizit zu implementierenIList
IList
Schnittstelle, tun dies jedoch explizit: msdn.microsoft.com/en-us/library/… . (Arrays implementieren auch die entsprechende generische IList<T>
Schnittstelle.)
ToList()
ist immer zu kopieren. Es wäre eine schreckliche Idee, die Methode manchmal kopieren zu lassen und manchmal nicht - dies würde zu ziemlich verrückten Aliasing-Fehlern führen. In der Tat von der Implementierung ToList()
ist mehr oder wenigerreturn new List(source)
Wenn der Index nicht sortiert ist, müssen Sie das Array mindestens einmal durchlaufen, um den höchsten Wert zu finden. Ich würde eine einfache verwendenfor
Schleife verwenden:
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;
}
}
Dies ist ausführlicher als etwas, das LINQ oder andere einzeilige Lösungen verwendet, aber es ist wahrscheinlich etwas schneller. Es gibt wirklich keine Möglichkeit, dies schneller als O (N) zu machen.
maxVal
den Indexwert bei Index 0 (vorausgesetzt, das Array hat mindestens die Länge 1) index
auf 0 initialisieren und die for-Schleife bei starten i = 1
.
Der obligatorische LINQ one [1] -Liner:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(Die Sortierung ist wahrscheinlich ein Leistungseinbruch gegenüber den anderen Lösungen.)
[1]: Für gegebene Werte von "eins".
Ein prägnanter Einzeiler:
var max = anArray.Select((n, i) => (Number: n, Index: i)).Max();
Testfall:
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.
Eigenschaften:
Hier sind zwei Ansätze. Möglicherweise möchten Sie eine Behandlung hinzufügen, wenn das Array leer ist.
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());
Ausgabe für folgenden Code:
00: 00: 00.3279270 - max1 00: 00: 00.2615935 - max2 00: 00: 00.6010360 - max3 (arr.Max ())
Mit 100000000 Ints im Array kein großer Unterschied, aber dennoch ...
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;
}
}
Dies funktioniert für alle Variablentypen ...
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);
Hier ist eine LINQ-Lösung, die O (n) mit anständigen konstanten Faktoren ist:
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);
Aber Sie sollten wirklich einen expliziten for
Lop schreiben, wenn Sie Wert auf Leistung legen.
Nur eine andere Perspektive mit DataTable
. Deklarieren Sie a DataTable
mit 2 Spalten index
und val
. Fügen Sie der Spalte eine AutoIncrement
Option und beide AutoIncrementSeed
und AutoIncrementStep
Werte hinzu . Verwenden Sie dann eine Schleife und fügen Sie jedes Array-Element als Zeile in das ein. Wählen Sie dann mit der Methode die Zeile mit dem Maximalwert aus.1
index
foreach
datatable
Select
Code
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]);
Ausgabe
Max Value = 7, Index = 4
Findet die größte und die kleinste Zahl im Array:
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);
Wenn Sie wissen, dass der maximale Indexzugriff sofort erfolgt, erfolgt der maximale Wert. Alles was Sie brauchen ist der maximale Index.
int max=0;
for(int i = 1; i < arr.Length; i++)
if (arr[i] > arr[max]) max = i;
Dies ist eine C # -Version. Es basiert auf der Idee, das Array zu sortieren.
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;
}
Beachten Sie Folgendes:
/// <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;
}
Verwendung:
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);