Reputation: 6606
So I have an unsorted numeric array int[] anArray = { 1, 5, 2, 7 };
and I need to get both the value and the index of the largest value in the array which would be 7 and 3, how would I do this?
Upvotes: 138
Views: 498764
Reputation: 19
int maxVal = anArray[0];
int maxIndex = 0;
for (int i =0;i< anArray.Length; i++)
{
if (anArray[i] > maxVal)
{
maxVal = anArray[i];
maxIndex = i;
}
}
Upvotes: 1
Reputation: 1
int[] numbers = { 1, 282, 343, 34, 0, 99, 43, 62, 75, 295 };
int biggestNo = numbers[0];
for (int I = 0; I < numbers.Length; I++) {
if (numbers[I] > biggestNo)
biggestNo = numbers[I];
}
Console.WriteLine(biggestNo);
}
Upvotes: -1
Reputation: 31
this works like a charm, no need for linq or other extensions
int[] anArray = { 1, 5, 2, 7 };
int i, mx;
int j = 0;
mx = anArray[0];
for (i = 1; i < anArray.Length; i++)
{
if (anArray[i] > mx)
{
mx = anArray[i];
j = i;
}
}
Console.Write("The largest value is: {0}, of index: {1}", mx, j);
Upvotes: 2
Reputation: 621
Old post, but this is super easy with Lists:
For Maximum:
List<int> lst = new List<int>(YourArray);
int Max = lst.OrderByDescending(x => x).First();
For Minimum:
List<int> lst = new List<int>(YourArray);
int Max = lst.OrderBy(x => x).First();
Of course you can substitute "int" data type with any numeric variable type (float, decimal, etc).
This is very high performance BTW and beats any other method (IMHO)
Upvotes: -1
Reputation: 902
A succinct one-liner:
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
Test case:
var anArray = new int[] { 1, 5, 7, 4, 2 };
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
Console.WriteLine($"Maximum number = {number}, on index {index}.");
// Maximum number = 7, on index 2.
Features:
Remarks:
Upvotes: 45
Reputation: 3539
Another answer in this long list, but I think it's worth it, because it provides some benefits that most (or all?) other answers don't:
min
, max
, equals
, not equals
, etc.///-------------------------------------------------------------------
/// <summary>
/// Get the indices of all values that meet the condition that is defined by the comparer.
/// </summary>
/// <typeparam name="TSource">The type of the values in the source collection.</typeparam>
/// <typeparam name="TCompare">The type of the values that are compared.</typeparam>
/// <param name="i_collection">The collection of values that is analysed.</param>
/// <param name="i_selector">The selector to retrieve the compare-values from the source-values.</param>
/// <param name="i_comparer">The comparer that is used to compare the values of the collection.</param>
/// <returns>The indices of all values that meet the condition that is defined by the comparer.</returns>
/// Create <see cref="IComparer{T}"/> from comparison function:
/// Comparer{T}.Create ( comparison )
/// Comparison examples:
/// - max: (a, b) => a.CompareTo (b)
/// - min: (a, b) => -(a.CompareTo (b))
/// - == x: (a, b) => a == 4 ? 0 : -1
/// - != x: (a, b) => a != 4 ? 0 : -1
///-------------------------------------------------------------------
public static IEnumerable<int> GetIndices<TSource, TCompare> (this IEnumerable<TSource> i_collection,
Func<TSource, TCompare> i_selector,
IComparer<TCompare> i_comparer)
{
if (i_collection == null)
throw new ArgumentNullException (nameof (i_collection));
if (!i_collection.Any ())
return new int[0];
int index = 0;
var indices = new List<int> ();
TCompare reference = i_selector (i_collection.First ());
foreach (var value in i_collection)
{
var compare = i_selector (value);
int result = i_comparer.Compare (compare, reference);
if (result > 0)
{
reference = compare;
indices.Clear ();
indices.Add (index);
}
else if (result == 0)
indices.Add (index);
index++;
}
return indices;
}
If you don't need the selector, then change the method to
public static IEnumerable<int> GetIndices<TCompare> (this IEnumerable<TCompare> i_collection,
IComparer<TCompare> i_comparer)
and remove all occurences of i_selector
.
//########## test #1: int array ##########
int[] test = { 1, 5, 4, 9, 2, 7, 4, 6, 5, 9, 4 };
// get indices of maximum:
var indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a.CompareTo (b)));
// indices: { 3, 9 }
// get indices of all '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 4 ? 0 : -1));
// indices: { 2, 6, 10 }
// get indices of all except '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a != 4 ? 0 : -1));
// indices: { 0, 1, 3, 4, 5, 7, 8, 9 }
// get indices of all '15':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 15 ? 0 : -1));
// indices: { }
//########## test #2: named tuple array ##########
var datas = new (object anything, double score)[]
{
(999, 0.1),
(new object (), 0.42),
("hello", 0.3),
(new Exception (), 0.16),
("abcde", 0.42)
};
// get indices of highest score:
indices = datas.GetIndices (data => data.score, Comparer<double>.Create ((a, b) => a.CompareTo (b)));
// indices: { 1, 4 }
Enjoy! :-)
Upvotes: 0
Reputation: 74730
This can be done with a bodiless for
loop, if we're heading towards 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) ;
The check of ++i<a.Length-1
omits checking the last index. We don't mind this if we set it up as if the max index is the last index to start with.. When the loop runs for the other elements it will finish and one or the other thing is true:
mi
mi
, and we stuck with the initial mi
The real work is done by the post-loop modifiers:
a[mi]
i.e. array indexed by mi
) we found so far, less than the current item?
mi
by remembering i
,mi
(no-op)At the end of the operation you have the index at which the max is to be found. Logically then the max value is a[mi]
I couldn't quite see how the "find max and index of max" really needed to track the max value too, given that if you have an array, and you know the index of the max value, the actual value of the max value is a trivial case of using the index to index the array..
Upvotes: 0
Reputation: 158
Consider following:
/// <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;
}
Usage:
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);
Upvotes: 0
Reputation: 115
This is a C# Version. It's based on the idea of sort the 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;
}
Upvotes: 0
Reputation:
If you know max index accessing the max value is immediate. So all you need is max index.
int max=0;
for(int i = 1; i < arr.Length; i++)
if (arr[i] > arr[max]) max = i;
Upvotes: 2
Reputation: 73
Finds the biggest and the smallest number in the 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);
Upvotes: -1
Reputation: 11566
Just another perspective using DataTable
. Declare a DataTable
with 2 columns called index
and val
. Add an AutoIncrement
option and both AutoIncrementSeed
and AutoIncrementStep
values 1
to the index
column. Then use a foreach
loop and insert each array item into the datatable
as a row. Then by using Select
method, select the row having the maximum value.
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]);
Output
Max Value = 7, Index = 4
Upvotes: 0
Reputation: 43636
This is not the most glamorous way but works.
(must have using System.Linq;
)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
Upvotes: 198
Reputation:
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);
}
Upvotes: 1
Reputation: 52157
Here is a LINQ solution which is O(n) with decent constant factors:
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);
But you should really write an explicit for
lop if you care about performance.
Upvotes: 0
Reputation: 804
public static class ArrayExtensions
{
public static int MaxIndexOf<T>(this T[] input)
{
var max = input.Max();
int index = Array.IndexOf(input, max);
return index;
}
}
This works for all variable types...
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();
Upvotes: 2
Reputation: 7437
Here are two approaches. You may want to add handling for when the array is empty.
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}");
}
Upvotes: 2
Reputation: 453
int[] Data= { 1, 212, 333,2,12,3311,122,23 };
int large = Data.Max();
Console.WriteLine(large);
Upvotes: 0
Reputation: 33
Output for bellow code:
00:00:00.3279270 - max1 00:00:00.2615935 - max2 00:00:00.6010360 - max3 (arr.Max())
With 100000000 ints in array not very big difference but still...
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;
}
Upvotes: 1
Reputation: 31
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);
Upvotes: 3
Reputation: 39990
The obligatory LINQ one[1]-liner:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(The sorting is probably a performance hit over the other solutions.)
[1]: For given values of "one".
Upvotes: 16
Reputation: 10991
If the index is not sorted, you have to iterate through the array at least once to find the highest value. I'd use a simple for
loop:
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;
}
}
This is more verbose than something using LINQ or other one-line solutions, but it's probably a little faster. There's really no way to make this faster than O(N).
Upvotes: 36
Reputation: 158
anArray.Select((n, i) => new { Value = n, Index = i })
.Where(s => s.Value == anArray.Max());
Upvotes: 0
Reputation: 734
int[] anArray = { 1, 5, 2, 7 };
// Finding max
int m = anArray.Max();
// Positioning max
int p = Array.IndexOf(anArray, m);
Upvotes: 53