I am trying to find the Occurrences of a Maximum value in Integer Array.
eg
int[] ar = [3, 1, 2, 3];
Here, the Max 3
is repeated twice and so the expected output is 2
.
This works, I am getting count as 2
as the max value 3
occurred twice in the array
var max = int.MinValue;
var occurrenceCount = 0;
foreach(var x in ar)
{
if (x >= max) max = x;
}
foreach(var x in ar)
{
if (x == max) occurrenceCount++;
}
Output: 2 //occurrenceCount
With Linq
it's more simple,
var occurrenceCount = ar.Count(x => x == ar.Max())
Output: 2 //occurrenceCount
Now without Linq
, Is there any simplified or efficient way to do this?
At least, you can merge the two first arrays. I would still use the Linq solution. It is clearer. If you really want to talk about performance read Which is faster? first.
So here is a O(n) solution:
int[] ar = {3, 1, 2, 3, 3, 4, 4};
int max = ar[0];
var occurrenceCount = 1;
for(var i = 1; i < ar.Length; i++)
{
if (ar[i] > max) {
max = ar[i];
occurrenceCount = 1;
}
else if (ar[i] == max) {
occurrenceCount++;
}
}
WriteLine(max);
WriteLine(occurrenceCount);
I did not use the linq. I used lamda :)
int[] ar = new[] { 3, 1, 2, 3 };
var result = ar.GroupBy(x => x) //values groups
.Select(x => new
{
Number = x.Key,
Count = x.Count()
}).OrderByDescending(x => x.Count) //Short
.FirstOrDefault(); //First Result
result.Count // how many
result.Key // max number
No Linq and No Lamda
int[] ar = new[] { 3, 1, 2, 3 };
Array.Sort(ar);
Array.Reverse(ar);
var maxValue = ar[0];
var occurrenceCount = 0;
foreach (var item in ar)
{
if (item == maxValue)
occurrenceCount++;
}
Based on both implementation of Max and GetCount on Enumerable you can simply factorise by adding one test in the foreach of the Max like :
public static int CountMax(this IEnumerable<int> source)
{
if (source == null)
{
throw new ArgumentException();
}
int value = 0;
bool hasValue = false;
int count = 0;
foreach (int x in source)
{
if (hasValue)
{
if (x > value)
{
value = x;
count = 1;
}
else if (x == value)
{
count++;
}
}
else
{
value = x;
count = 1;
hasValue = true;
}
}
if (hasValue)
{
return count;
}
throw new Exception("no elements");
}
The cool part is that it's easy to make it more generik like :
public static int CountMax<TSource>(this IEnumerable<TSource> source) where TSource : IComparable
You can try more flexible approach:
using System.Collections.Generic;
namespace ConsoleApp42
{
class Program
{
static void Main (string[] args)
{
var array = new int[] { 1, 2, 3, 1, 1, 4, 4, 4, 4, 1, 1, 1 };
//var array = new string[] { "a", "b", "a", "a" };
var result = array.MaxCount ();
}
}
public static class Extensions
{
public static (long count, T max) MaxCount<T> (this IEnumerable<T> source, IComparer<T> comparer = null)
{
if (comparer is null) comparer = Comparer<T>.Default;
(long count, T max) result = (0, default (T));
foreach (var element in source)
{
if (result.count == 0) // is first element?
{
result.max = element;
result.count = 1;
continue;
}
int compareResult = comparer.Compare (element, result.max);
if (compareResult == 0) // element == max
{
result.count++;
}
else if (compareResult > 0) // element > max
{
result.max = element;
result.count = 1;
}
}
return result;
}
}
}
int[] list = new int[] { 1, 1, 2, 3, 6, 7, 6, 6, 6, 8, 9 };
Dictionary<int, int> occ = new Dictionary<int, int>();
for (int i = 0; i < list.Length; i++)
{
var val = list[i];
var count = 0;
for (int j = 0; j < list.Length; j++)
{
if (val == list[j])
{
count++;
}
}
occ.TryAdd(val, count);
}
var maxCount = occ.Values.Max();
var repNumber = occ.FirstOrDefault(x => x.Value == maxCount).Key;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.