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?
Bisher habe ich versucht, die Max () -Methode zu verwenden und dann die binäre Suchmethode zu verwenden, um den Index dieses Maximalwerts zu erhalten. Dies funktioniert jedoch nur, wenn das Array sortiert ist, sodass ich es nicht verwenden kann, als ich versuchte, negative Zahlen zu erhalten
Edmund Rojas
@EdmundRojas Sie müssen keine binäre Suche verwenden. Eine einfache alte lineare Suche funktioniert gut für unsortierte Listen.
Millimoose
Antworten:
137
Dies ist nicht der glamouröseste Weg, sondern funktioniert.
(muss haben using System.Linq;)
int maxValue = anArray.Max();int maxIndex = anArray.ToList().IndexOf(maxValue);
Sie sparen viel Zeit beim Codieren, gehen die Sammlung jedoch zweimal durch.
Garo Yeriazarian
10
Sie brauchen nicht einmal die .ToList()Arrays explizit zu implementierenIList
Millimoose
@GaroYeriazarian Wenn die lineare Komplexität für Ihren Anwendungsfall zu groß ist, müssen Sie wahrscheinlich mehr als nur den konstanten Faktor um ein Drittel reduzieren. (Obwohl es offensichtlich keine vernachlässigbare Optimierung ist.)
Millimoose
1
@ sa_ddam213 Arrays implementieren die IList Schnittstelle, tun dies jedoch explizit: msdn.microsoft.com/en-us/library/… . (Arrays implementieren auch die entsprechende generische IList<T>Schnittstelle.)
Millimoose
1
@ sa_ddam213 Nein, der Vertrag von 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)
millimoose
42
int[] anArray ={1,5,2,7};// Finding maxint m = anArray.Max();// Positioning maxint p =Array.IndexOf(anArray, m);
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 negativesint 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.
Sie können eine Iteration speichern, indem Sie maxValden Indexwert bei Index 0 (vorausgesetzt, das Array hat mindestens die Länge 1) indexauf 0 initialisieren und die for-Schleife bei starten i = 1.
Jon Schneider
13
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.)
Nur um diese Lösung hinzuzufügen, ist bestenfalls O (nlogn) Komplexität. Das Finden von max kann in O (n) Zeit für ein unsortiertes Array erhalten werden.
Dopplesoldner
12
Ein prägnanter Einzeiler:
var max = anArray.Select((n, i)=>(Number: n,Index: i)).Max();
Testfall:
var anArray =newint[]{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:
Verwendet Linq (nicht so optimiert wie Vanille, aber der Kompromiss ist weniger Code).
Hier sind zwei Ansätze. Möglicherweise möchten Sie eine Behandlung hinzufügen, wenn das Array leer ist.
publicstaticvoidFindMax(){// 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 understandint[]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}");}publicstaticvoidFindMax2(){// Advantages: // * Near-optimal performanceint[]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 conditionfor(int i =0; i <array.Length; i++){intvalue=array[i];if(value> maxInt){
maxInt =value;
maxIndex = i;}}Console.WriteLine($"Maximum int {maxInt} is found at index {maxIndex}");}
publicstaticclassArrayExtensions{publicstaticintMaxIndexOf<T>(this T[] input){var max = input.Max();int index =Array.IndexOf(input, max);return index;}}
Dies funktioniert für alle Variablentypen ...
vararray=newint[]{1,2,4,10,0,2};var index =array.MaxIndexOf();vararray=newdouble[]{1.0,2.0,4.0,10.0,0.0,2.0};var index =array.MaxIndexOf();
Nur eine andere Perspektive mit DataTable. Deklarieren Sie a DataTablemit 2 Spalten indexund val. Fügen Sie der Spalte eine AutoIncrementOption und beide AutoIncrementSeedund AutoIncrementStepWerte 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.1indexforeachdatatableSelect
Code
int[] anArray ={1,5,2,7};DataTable dt =newDataTable();
dt.Columns.AddRange(newDataColumn[2]{newDataColumn("index"),newDataColumn("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]);
int[] arr =newint[]{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);
Dies ist eine C # -Version. Es basiert auf der Idee, das Array zu sortieren.
publicint 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)return1;elsefor(int i =1; i < max; i++){if(!A.Contains(i)){return i;}}return max +1;}
/// <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>publicstaticintMaxAt(int[] arr,outint 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(newint[]{1,2,7,3,4,5,6},out at);Console.WriteLine("Max: {0}, found at: {1}", m, at);
Antworten:
Dies ist nicht der glamouröseste Weg, sondern funktioniert.
(muss haben
using System.Linq;
)quelle
.ToList()
Arrays explizit zu implementierenIList
IList
Schnittstelle, tun dies jedoch explizit: msdn.microsoft.com/en-us/library/… . (Arrays implementieren auch die entsprechende generischeIList<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 ImplementierungToList()
ist mehr oder wenigerreturn new List(source)
quelle
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 verwenden
for
Schleife verwenden: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.
quelle
maxVal
den Indexwert bei Index 0 (vorausgesetzt, das Array hat mindestens die Länge 1)index
auf 0 initialisieren und die for-Schleife bei starteni = 1
.Der obligatorische LINQ one [1] -Liner:
(Die Sortierung ist wahrscheinlich ein Leistungseinbruch gegenüber den anderen Lösungen.)
[1]: Für gegebene Werte von "eins".
quelle
Ein prägnanter Einzeiler:
Testfall:
Eigenschaften:
quelle
Hier sind zwei Ansätze. Möglicherweise möchten Sie eine Behandlung hinzufügen, wenn das Array leer ist.
quelle
quelle
quelle
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 ...
quelle
Dies funktioniert für alle Variablentypen ...
quelle
quelle
quelle
Hier ist eine LINQ-Lösung, die O (n) mit anständigen konstanten Faktoren ist:
Aber Sie sollten wirklich einen expliziten
for
Lop schreiben, wenn Sie Wert auf Leistung legen.quelle
Nur eine andere Perspektive mit
DataTable
. Deklarieren Sie aDataTable
mit 2 Spaltenindex
undval
. Fügen Sie der Spalte eineAutoIncrement
Option und beideAutoIncrementSeed
undAutoIncrementStep
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
Ausgabe
Hier finden Sie eine Demo
quelle
Findet die größte und die kleinste Zahl im Array:
quelle
Wenn Sie wissen, dass der maximale Indexzugriff sofort erfolgt, erfolgt der maximale Wert. Alles was Sie brauchen ist der maximale Index.
quelle
Dies ist eine C # -Version. Es basiert auf der Idee, das Array zu sortieren.
quelle
Beachten Sie Folgendes:
Verwendung:
quelle