tags:

views:

462

answers:

3

How to get the most common value in an Int array using C#

eg: Array has the following values: 1, 1, 1, 2

Ans should be 1

+11  A: 
var query = (from item in array
        group item by item into g
        orderby g.Count() descending
        select new { Item = g.Key, Count = g.Count() }).First();

For just the value and not the count, you can do

var query = (from item in array
                group item by item into g
                orderby g.Count() descending
                select g.Key).First();

Lambda version on the second:

var query = array.GroupBy(item => item).OrderByDescending(g => g.Count()).Select(g => g.Key).First();
Anthony Pegram
+1 dangit, better and quicker than mine.
Patrick Karcher
Isn't this doing O(nlogn) sorting?
liori
@liori: Yes. Sorting isn't the most efficient way of finding the highest count.
Guffa
+6  A: 

Some old fashioned efficient looping:

var cnt = new Dictionary<int, int>();
foreach (int value in theArray) {
   if (cnt.ContainsKey(value)) {
      cnt[value]++;
   } else {
      cnt.Add(value, 1);
   }
}
int mostCommonValue = 0;
int highestCount = 0;
foreach (KeyValuePair<int, int> pair in cnt) {
   if (pair.Value > highestCount) {
      mostCommonValue = pair.Key;
      highestCount = pair.Value;
   }
}

Now mostCommonValue contains the most common value, and highestCount contains how many times it occured.

Guffa
+1 Nothing wrong with busting out the elbow grease and getting it done.
Anthony Pegram
A: 

Maybe O(n log n), but fast:

sort the array a[n]

// assuming n > 0
int iBest = -1;  // index of first number in most popular subset
int nBest = -1;  // popularity of most popular number
// for each subset of numbers
for(int i = 0; i < n; ){
  int ii = i; // ii = index of first number in subset
  int nn = 0; // nn = count of numbers in subset
  // for each number in subset, count it
  for (; i < n && a[i]==a[ii]; i++, nn++ ){}
  // if the subset has more numbers than the best so far
  // remember it as the new best
  if (nBest < nn){nBest = nn; iBest = ii;}
}

// print the most popular value and how popular it is
print a[iBest], nBest
Mike Dunlavey
You didn't say sort the array at first :). Anyway, you can do this simpler if you're going to sort. One for loop and a few variables should be enough.
IVlad
@IVlad: wasn't that the first line of code? Anyway, you're right.
Mike Dunlavey