-2

Essentially, I found an old piece of LINQ C# code that counted the most frequent letter in a certain string. However, I'm using frequency analysis to solve a decoded text that has been shift-ciphered so I'm wanting it to return not just the most popular char, but a char array ordered by frequency of appearance.

Here is the LINQ code I found on here:

input.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key
samil90
  • 107
  • 6
  • 7
    Oh come on, is this a "do my work for me" question? I suggest you go learn LINQ, and understand what that piece of code does. **Who the heck upvotes this?** – R. Martinho Fernandes Nov 25 '11 at 17:00
  • What do you want? Do you want to know whether this code is good? Or do you want an optimized version? – Aamir Nov 25 '11 at 17:02
  • Believe me R. Martinho Fernandes, I have been out of the loop for some time, never used LINQ before and I've exhausted myself trying to research how I can do this. Thought I might be able to get help on here – samil90 Nov 25 '11 at 17:04
  • Since you never used LINQ before, I stand by my suggestion of learning LINQ. – R. Martinho Fernandes Nov 25 '11 at 17:05
  • I'll only be using it for this one piece of string-searching. I don't think learning LINQ will be appropriate given my time constraints. – samil90 Nov 25 '11 at 17:06

5 Answers5

2

Replacing .First().Key with .Select(group => group.Key) should return to you the characters sorted by frequency in descending order.

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
2

Well you pretty much have it already.

input.GroupBy(x => x).OrderByDescending(x => x.Count()).Select(x => x.Key).ToArray();
Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94
2

Here's a solution that doesn't use LINQ, which might be understandable without learning LINQ:

// count all the frequencies
var frequencies = new Dictionary<char, int>;
foreach(char c in input)
{
    if(frequencies.ContainsKey(c))
    {
        frequencies[c]++;
    }
    else
    {
        frequencies.Add(c, 1);
    }
}
// Get the characters
var characters = new List<char>(frequencies.Keys);
// Sort them
characters.Sort((x, y) => frequencies[x].CompareTo(frequencies[y]));
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
1
input.GroupBy(x => x).OrderByDescending(x => x.Count()).Select(group => group.Key).ToArray();
Tom Carver
  • 962
  • 7
  • 17
1

The information is all there, just don't throw it away:

Dictionary<char, int> count =
  input.GroupBy(g => g).ToDictionary(g => g.Key, g => g.Count());

Oh, right, you just want the characters, not their frequency. Then you have to throw away some of the information:

char[] chars =
  input.GroupBy(g => g).OrderByDescending(g => g.Count()).Select(g => g.Key)
  .ToArray();
Guffa
  • 687,336
  • 108
  • 737
  • 1,005