Yani sıralanmamış bir sayısal dizim var int[] anArray = { 1, 5, 2, 7 };
ve dizideki en büyük değerin hem değerini hem de dizinini almam gerekiyor ki bu 7 ve 3 olacaktır, bunu nasıl yapacağım?
Yani sıralanmamış bir sayısal dizim var int[] anArray = { 1, 5, 2, 7 };
ve dizideki en büyük değerin hem değerini hem de dizinini almam gerekiyor ki bu 7 ve 3 olacaktır, bunu nasıl yapacağım?
Yanıtlar:
Bu en göz alıcı yol değil ama işe yarıyor.
(olmalı using System.Linq;
)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
.ToList()
Dizilerin açıkça uygulanmasına bile ihtiyacınız yokIList
IList
arabirimi uygular , ancak bunu açıkça yaparlar: msdn.microsoft.com/en-us/library/… . (Diziler ayrıca ilgili genel IList<T>
arabirimi de uygular .)
ToList()
her zaman kopyalamaktır. Yöntemin bazen kopyalanması bazen de kopyalanmaması korkunç bir fikir olurdu - bu oldukça çılgınca takma ad hatalarına yol açar. Aslında, uygulaması ToList()
aşağı yukarıreturn new List(source)
Dizin sıralanmamışsa, en yüksek değeri bulmak için dizide en az bir kez yineleme yapmanız gerekir. Basit bir for
döngü kullanırım:
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;
}
}
Bu, LINQ veya diğer tek satırlık çözümleri kullanan bir şeyden daha ayrıntılıdır, ancak muhtemelen biraz daha hızlıdır. Bunu O (N) 'den daha hızlı yapmanın gerçekten bir yolu yok.
maxVal
0 dizinindeki dizi değerini (dizinin en az 1 uzunluğunda olduğu varsayılarak) index
0'a başlatarak ve for döngüsünü de başlatarak bir yineleme kaydedebilirsiniz i = 1
.
Zorunlu LINQ one [1] -liner:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(Sıralama, muhtemelen diğer çözümlere göre bir performans artışıdır.)
[1]: Verilen "bir" değerleri için.
Kısa ve öz bir tek satır:
var max = anArray.Select((n, i) => (Number: n, Index: i)).Max();
Test durumu:
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.
Özellikleri:
Uyarılar:
anArray.Select((n, i) => ( Index: i, Number: n)).Max()
tuple'ların karşılaştırılma şekli nedeniyle maksimum sayı yerine maksimum indeksi bulur (öğe1 en önemli olanı vb.)
İşte iki yaklaşım. Dizi boş olduğunda işlem eklemek isteyebilirsiniz.
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());
Aşağıdaki kod için çıktı:
00: 00: 00.3279270 - maks1 00: 00: 00.2615935 - maks2 00: 00: 00.6010360 - maks3 (aralık.Maks ())
Dizideki 100000000 inç ile çok büyük bir fark değil ama yine de ...
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;
}
}
Bu, tüm değişken türleri için çalışır ...
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);
İşte iyi sabit faktörlerle O (n) olan bir LINQ çözümü:
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);
Ancak for
performansı önemsiyorsanız , gerçekten açık bir söz yazmalısınız .
Sadece başka bir perspektif kullanarak DataTable
. Ve DataTable
adlı 2 sütunlu bir beyan edin . Bir ekleme seçeneği ve her ikisi ve değerler için sütunda. Sonra bir döngü kullanın ve her dizi öğesini bir satır olarak ekleyin . Daha sonra yöntemi kullanarak maksimum değere sahip satırı seçin.index
val
AutoIncrement
AutoIncrementSeed
AutoIncrementStep
1
index
foreach
datatable
Select
Kod
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]);
Çıktı
Max Value = 7, Index = 4
Dizideki en büyük ve en küçük sayıyı bulur:
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);
Maksimum değere erişimin maksimum indeksini biliyorsanız hemen olur. Yani ihtiyacınız olan tek şey maksimum indeks.
int max=0;
for(int i = 1; i < arr.Length; i++)
if (arr[i] > arr[max]) max = i;
Aşağıdakileri düşünün:
/// <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;
}
Kullanım:
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);
Bu, for
golfe doğru gidersek, bedensiz bir döngü ile yapılabilir ;)
//a is the array
int mi = a.Length - 1;
for (int i=-1; ++i<a.Length-1; mi=a[mi]<a[i]?i:mi) ;
Onay ++i<a.Length-1
son endeksini kontrol atlar. Bunu, maks. İndeks başlayacak son indeksmiş gibi ayarlarsak bunu umursamayız .. Döngü diğer öğeler için çalıştığında biter ve bir veya diğer şey doğrudur:
mi
mi
ve baştakimi
Gerçek iş, döngü sonrası değiştiriciler tarafından yapılır:
a[mi]
yani dizine göre dizine alınmış mi
), mevcut öğeden daha mı az?
mi
hatırlayarak yenisini saklayıni
,mi
(işlemsiz)İşlemin sonunda maksimumun bulunacağı dizine sahipsiniz. Mantıksal olarak maksimum değer şu şekildedir:a[mi]
Bir diziniz varsa ve maksimum değerin dizinini, maksimum değerin gerçek değerini biliyorsanız, maksimum değeri izlemek için gerçekten de "maks ve maksimum indeksini bul" un nasıl gerekli olduğunu tam olarak anlayamadım diziyi indekslemek için indeksi kullanmanın önemsiz bir durumudur ..