Jadi saya memiliki array numerik yang tidak diurutkan int[] anArray = { 1, 5, 2, 7 };dan saya perlu mendapatkan nilai dan indeks dari nilai terbesar dalam array yang akan menjadi 7 dan 3, bagaimana saya melakukan ini?
Sejauh ini saya mencoba menggunakan metode Max () dan kemudian menggunakan metode pencarian biner untuk mendapatkan indeks dari nilai maks itu tetapi ini tidak berfungsi kecuali array diurutkan jadi saya tidak dapat menggunakannya, ketika saya mencoba itu memberi saya angka negatif
Edmund Rojas
@EdmundRojas Anda tidak perlu menggunakan pencarian biner. Pencarian linier biasa bekerja dengan baik untuk daftar yang tidak diurutkan.
millimoose
Jawaban:
145
Ini bukan cara yang paling glamor tapi berhasil.
(harus punya using System.Linq;)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
Anda menghemat banyak waktu pengkodean, tetapi pada akhirnya Anda akan melalui pengumpulan dua kali.
Garo Yeriazarian
11
Anda bahkan tidak memerlukan .ToList(), larik yang diimplementasikan secara eksplisitIList
millimoose
@GaroYeriazarian Jika kompleksitas linier terlalu banyak untuk kasus penggunaan Anda, Anda mungkin perlu mengurangi lebih dari sekadar mengurangi faktor konstanta sepertiga. (Meskipun jelas ini bukan pengoptimalan yang dapat diabaikan.)
millimoose
1
@ sa_ddam213 Array mengimplementasikan IListantarmuka, tetapi mereka melakukannya secara eksplisit: msdn.microsoft.com/en-us/library/… . (Array juga menerapkan IList<T>antarmuka umum yang sesuai .)
millimoose
1
@ sa_ddam213 Tidak, kontraknya ToList()adalah untuk selalu menyalin. Akan menjadi ide yang buruk untuk memiliki metode yang kadang-kadang menyalin dan terkadang tidak - ini akan menyebabkan bug aliasing yang cukup gila. Faktanya penerapannya ToList()lebih atau kurangreturn new List(source)
Jika indeks tidak diurutkan, Anda harus mengulang melalui array setidaknya sekali untuk menemukan nilai tertinggi. Saya akan menggunakan forloop sederhana :
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;
}
}
Ini lebih bertele-tele daripada sesuatu yang menggunakan LINQ atau solusi satu baris lainnya, tetapi mungkin sedikit lebih cepat. Benar-benar tidak ada cara untuk membuat ini lebih cepat dari O (N).
Anda dapat menyimpan satu iterasi dengan menginisialisasi maxValke nilai array pada indeks 0 (dengan asumsi array setidaknya panjang 1), indexke 0, dan memulai perulangan for di i = 1.
Jon Schneider
14
LINQ wajib satu [1] -liner:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(Penyortiran mungkin merupakan kinerja yang terpukul di atas solusi lain.)
Hanya untuk menambahkan solusi ini adalah kompleksitas O (nlogn) yang terbaik. Menemukan nilai maks dapat diperoleh dalam waktu O (n) untuk larik yang tidak disortir.
dopplesoldner
13
Satu kalimat yang ringkas:
var max = anArray.Select((n, i) => (Number: n, Index: i)).Max();
Kasus cobaan:
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.
Fitur:
Menggunakan Linq (tidak dioptimalkan seperti vanilla, tetapi trade-offnya adalah lebih sedikit kode).
Tidak perlu diurutkan.
Kompleksitas komputasi: O (n).
Kompleksitas ruang: O (n).
Catatan:
Pastikan nomor (dan bukan indeks) adalah elemen pertama dalam tupel karena penyortiran tupel dilakukan dengan membandingkan item tupel dari kiri ke kanan.
Harus ditunjukkan bahwa agar ini berfungsi, item yang dimaksimalkan harus terlebih dahulu
Caius Jard
Apa maksudmu @CaiusJard? Seperti yang ditunjukkan dalam kasus uji, item maksimum ditemukan dengan benar dan terakhir.
Lesair Valmont
Pertama di Tuple, misalnya anArray.Select((n, i) => ( Index: i, Number: n)).Max()menemukan indeks maks daripada jumlah maks karena cara tupel dibandingkan (item1 paling signifikan dll)
Caius Jard
Cukup adil @CaiusJard, saya menambahkan komentar untuk menunjukkannya. Terima kasih.
Lesair Valmont
3
Berikut dua pendekatan. Anda mungkin ingin menambahkan penanganan saat array kosong.
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}");
}
Dengan 100000000 int dalam array perbedaan yang tidak terlalu besar tetapi masih ...
classProgram
{
staticvoidMain(string[] args)
{
int[] arr = newint[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());
}
privatestaticintGetMaxPartialIterate(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;
}
privatestaticintGetMaxFullIterate(int[] arr)
{
var max = arr[0];
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
publicstaticclassArrayExtensions
{
publicstaticintMaxIndexOf<T>(this T[] input)
{
var max = input.Max();
int index = Array.IndexOf(input, max);
return index;
}
}
Ini berfungsi untuk semua jenis variabel ...
var array = newint[]{1, 2, 4, 10, 0, 2};
var index = array.MaxIndexOf();
var array = newdouble[]{1.0, 2.0, 4.0, 10.0, 0.0, 2.0};
var index = array.MaxIndexOf();
Hanya menggunakan perspektif lain DataTable. Deklarasikan a DataTabledengan 2 kolom yang disebut indexdan val. Tambahkan AutoIncrementopsi dan keduanya AutoIncrementSeedserta AutoIncrementStepnilai 1ke indexkolom. Kemudian gunakan foreachloop dan masukkan setiap item array ke dalam datatablebaris sebagai. Kemudian dengan menggunakan Selectmetode, pilih baris yang memiliki nilai maksimum.
Kode
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]);
Menemukan angka terbesar dan terkecil dalam array:
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);
Ini adalah Versi C #. Ini didasarkan pada gagasan mengurutkan array.
publicintsolution(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;
}
Pemakaian:
int m, at;
m = MaxAt(newint[]{1,2,7,3,4,5,6}, out at);
Console.WriteLine("Max: {0}, found at: {1}", m, at);
Ini bisa dilakukan dengan forloop tanpa tubuh, jika kita menuju golf;)
//a is the arrayint mi = a.Length - 1;
for (int i=-1; ++i<a.Length-1; mi=a[mi]<a[i]?i:mi) ;
Pemeriksaan ++i<a.Length-1kelalaian memeriksa indeks terakhir. Kami tidak keberatan jika kami mengaturnya seolah-olah indeks maks adalah indeks terakhir untuk memulai .. Ketika loop berjalan untuk elemen lain, itu akan selesai dan satu atau hal lain benar:
kami menemukan nilai maks baru dan karenanya indeks maks baru mi
indeks terakhir adalah nilai maksimal selama ini, jadi kami tidak menemukan yang baru mi, dan kami terjebak dengan yang awalmi
Pekerjaan sebenarnya dilakukan oleh pengubah post-loop:
adalah nilai maks ( a[mi]yaitu array yang diindeks oleh mi) yang kami temukan sejauh ini, kurang dari item saat ini?
ya, lalu simpan yang baru midengan mengingat i,
tidak maka simpan yang ada mi(no-op)
Di akhir operasi Anda memiliki indeks di mana nilai maksimum dapat ditemukan. Logikanya, nilai maksimalnya adalaha[mi]
Saya tidak bisa melihat bagaimana "temukan maks dan indeks maks" benar-benar diperlukan untuk melacak nilai maks juga, mengingat jika Anda memiliki larik, dan Anda tahu indeks nilai maks, nilai sebenarnya dari nilai maks adalah kasus sepele menggunakan indeks untuk mengindeks larik ..
Jawaban:
Ini bukan cara yang paling glamor tapi berhasil.
(harus punya
using System.Linq;
)int maxValue = anArray.Max(); int maxIndex = anArray.ToList().IndexOf(maxValue);
sumber
.ToList()
, larik yang diimplementasikan secara eksplisitIList
IList
antarmuka, tetapi mereka melakukannya secara eksplisit: msdn.microsoft.com/en-us/library/… . (Array juga menerapkanIList<T>
antarmuka umum yang sesuai .)ToList()
adalah untuk selalu menyalin. Akan menjadi ide yang buruk untuk memiliki metode yang kadang-kadang menyalin dan terkadang tidak - ini akan menyebabkan bug aliasing yang cukup gila. Faktanya penerapannyaToList()
lebih atau kurangreturn new List(source)
int[] anArray = { 1, 5, 2, 7 }; // Finding max int m = anArray.Max(); // Positioning max int p = Array.IndexOf(anArray, m);
sumber
Jika indeks tidak diurutkan, Anda harus mengulang melalui array setidaknya sekali untuk menemukan nilai tertinggi. Saya akan menggunakan
for
loop sederhana :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; } }
Ini lebih bertele-tele daripada sesuatu yang menggunakan LINQ atau solusi satu baris lainnya, tetapi mungkin sedikit lebih cepat. Benar-benar tidak ada cara untuk membuat ini lebih cepat dari O (N).
sumber
maxVal
ke nilai array pada indeks 0 (dengan asumsi array setidaknya panjang 1),index
ke 0, dan memulai perulangan for dii = 1
.LINQ wajib satu [1] -liner:
var max = anArray.Select((value, index) => new {value, index}) .OrderByDescending(vi => vi.value) .First();
(Penyortiran mungkin merupakan kinerja yang terpukul di atas solusi lain.)
[1]: Untuk nilai "satu" yang diberikan.
sumber
Satu kalimat yang ringkas:
var max = anArray.Select((n, i) => (Number: n, Index: i)).Max();
Kasus cobaan:
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.
Fitur:
Catatan:
sumber
anArray.Select((n, i) => ( Index: i, Number: n)).Max()
menemukan indeks maks daripada jumlah maks karena cara tupel dibandingkan (item1 paling signifikan dll)Berikut dua pendekatan. Anda mungkin ingin menambahkan penanganan saat array kosong.
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}"); }
sumber
anArray.Select((n, i) => new { Value = n, Index = i }) .Where(s => s.Value == anArray.Max());
sumber
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);
sumber
Output untuk kode di bawah ini:
00: 00: 00.3279270 - maks1 00: 00: 00.2615935 - maks2 00: 00: 00.6010360 - maks3 (arr.Max ())
Dengan 100000000 int dalam array perbedaan yang tidak terlalu besar tetapi masih ...
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; }
sumber
public static class ArrayExtensions { public static int MaxIndexOf<T>(this T[] input) { var max = input.Max(); int index = Array.IndexOf(input, max); return index; } }
Ini berfungsi untuk semua jenis variabel ...
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();
sumber
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); }
sumber
int[] Data= { 1, 212, 333,2,12,3311,122,23 }; int large = Data.Max(); Console.WriteLine(large);
sumber
Berikut adalah solusi LINQ yaitu O (n) dengan faktor konstanta yang layak:
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);
Tetapi Anda harus benar-benar menulis
for
lop eksplisit jika Anda peduli dengan kinerja.sumber
Hanya menggunakan perspektif lain
DataTable
. Deklarasikan aDataTable
dengan 2 kolom yang disebutindex
danval
. TambahkanAutoIncrement
opsi dan keduanyaAutoIncrementSeed
sertaAutoIncrementStep
nilai1
keindex
kolom. Kemudian gunakanforeach
loop dan masukkan setiap item array ke dalamdatatable
baris sebagai. Kemudian dengan menggunakanSelect
metode, pilih baris yang memiliki nilai maksimum.Kode
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]);
Keluaran
Max Value = 7, Index = 4
Temukan demo di sini
sumber
Menemukan angka terbesar dan terkecil dalam 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);
sumber
Jika Anda tahu indeks maks mengakses nilai maks langsung. Jadi yang Anda butuhkan hanyalah indeks maks.
int max=0; for(int i = 1; i < arr.Length; i++) if (arr[i] > arr[max]) max = i;
sumber
Ini adalah Versi C #. Ini didasarkan pada gagasan mengurutkan array.
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; }
sumber
Pertimbangkan berikut ini:
/// <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; }
Pemakaian:
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);
sumber
Ini bisa dilakukan dengan
for
loop tanpa tubuh, jika kita menuju 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) ;
Pemeriksaan
++i<a.Length-1
kelalaian memeriksa indeks terakhir. Kami tidak keberatan jika kami mengaturnya seolah-olah indeks maks adalah indeks terakhir untuk memulai .. Ketika loop berjalan untuk elemen lain, itu akan selesai dan satu atau hal lain benar:mi
mi
, dan kami terjebak dengan yang awalmi
Pekerjaan sebenarnya dilakukan oleh pengubah post-loop:
a[mi]
yaitu array yang diindeks olehmi
) yang kami temukan sejauh ini, kurang dari item saat ini?mi
dengan mengingati
,mi
(no-op)Di akhir operasi Anda memiliki indeks di mana nilai maksimum dapat ditemukan. Logikanya, nilai maksimalnya adalah
a[mi]
Saya tidak bisa melihat bagaimana "temukan maks dan indeks maks" benar-benar diperlukan untuk melacak nilai maks juga, mengingat jika Anda memiliki larik, dan Anda tahu indeks nilai maks, nilai sebenarnya dari nilai maks adalah kasus sepele menggunakan indeks untuk mengindeks larik ..
sumber