例如,我有一个字符串:
"abbbbccd"
b
发生次数最多。使用C ++时,处理此问题的最简单方法是将每个字符插入map<>
。我是否必须在C#中做同样的事情?使用LINQ有一种优雅的方式吗?
答案 0 :(得分:28)
input.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key
注意:
"aaaabbbb"
的情况,只返回其中一个(感谢xanatos进行评论)。如果您需要所有具有最大数量的元素,请改用Albin's solution。答案 1 :(得分:10)
这是因为有人要求提供2.0版本,所以没有LINQ。
Dictionary<char, int> dict = new Dictionary<char, int>();
int max = 0;
foreach (char c in "abbbbccccd")
{
int i;
dict.TryGetValue(c, out i);
i++;
if (i > max)
{
max = i;
}
dict[c] = i;
}
foreach (KeyValuePair<char, int> chars in dict)
{
if (chars.Value == max)
{
Console.WriteLine("{0}: {1}", chars.Key, chars.Value);
}
}
而不是LINQ版本。它将提取成对的“bests”(aaaabbbb == a,b)。如果str == String.Empty,它将无法工作。
var str = "abbbbccccd";
var res = str.GroupBy(p => p).Select(p => new { Count = p.Count(), Char = p.Key }).GroupBy(p => p.Count, p => p.Char).OrderByDescending(p => p.Key).First();
foreach (var r in res) {
Console.WriteLine("{0}: {1}", res.Key, r);
}
答案 2 :(得分:8)
string testString = "abbbbccd";
var charGroups = (from c in testString
group c by c into g
select new
{
c = g.Key,
count = g.Count(),
}).OrderByDescending(c => c.count);
foreach (var group in charGroups)
{
Console.WriteLine(group.c + ": " + group.count);
}
答案 3 :(得分:3)
受到斯蒂芬答案的启发,几乎一样:
public static IEnumerable<T> Mode<T>(this IEnumerable<T> input)
{
var dict = input.ToLookup(x => x);
if (dict.Count == 0)
return Enumerable.Empty<T>();
var maxCount = dict.Max(x => x.Count());
return dict.Where(x => x.Count() == maxCount).Select(x => x.Key);
}
var modes = "".Mode().ToArray(); //returns { }
var modes = "abc".Mode().ToArray(); //returns { a, b, c }
var modes = "aabc".Mode().ToArray(); //returns { a }
var modes = "aabbc".Mode().ToArray(); //returns { a, b }
更新:快速对此答案进行基准测试与Jodrell's回答(发布版本,调试器分离,是的)
source =“”;
iterations = 1000000
结果:
this - 280 ms
Jodrell's - 900 ms
source =“aabc”;
iterations = 1000000
结果:
this - 1800 ms
Jodrell's - 3200 ms
source =相当大的字符串 - 3500+ char
iterations = 10000
结果:
this - 3200 ms
Jodrell's - 3000 ms
答案 4 :(得分:2)
编辑3
这是我的最后一个答案,我认为(只是)将Nawfal用于较长序列的表现。
然而,考虑到Nawfal's answer的复杂性降低及其更普遍的表现,特别是与问题有关,我会选择它。
public static IEnumerable<T> Mode<T>(
this IEnumerable<T> source,
IEqualityComparer<T> comparer = null)
{
var counts = source.GroupBy(t => t, comparer)
.Select(g => new { g.Key, Count = g.Count() })
.ToList();
if (counts.Count == 0)
{
return Enumerable.Empty<T>();
}
var maxes = new List<int>(5);
int maxCount = 1;
for (var i = 0; i < counts.Count; i++)
{
if (counts[i].Count < maxCount)
{
continue;
}
if (counts[i].Count > maxCount)
{
maxes.Clear();
maxCount = counts[i].Count;
}
maxes.Add(i);
}
return maxes.Select(i => counts[i].Key);
}
编辑2
修改强>
如果您想要一个有效的通用解决方案,这可以说明多个项目可能具有相同的频率,请从此扩展程序开始,
IOrderedEnumerable<KeyValuePair<int, IEnumerable<T>>>Frequency<T>(
this IEnumerable<T> source,
IComparer<T> comparer = null)
{
return source.GroupBy(t => t, comparer)
.GroupBy(
g => g.Count(),
(k, s) => new KeyValuePair<int, IEnumerable<T>>(
k,
s.Select(g => g.First())))
.OrderByDescending(f => f.Key);
}
此扩展适用于以下所有方案
var mostFrequent = string.Empty.Frequency().FirstOrDefault();
var mostFrequent = "abbbbccd".Frequency().First();
,或者
var mostFrequent = "aaacbbbcdddceee".Frequency().First();
请注意,mostFrequent
是KeyValuePair<int, IEnumerable<char>>
。
如果有这样的想法,你可以将其简化为另一个扩展,
public static IEnumerable<T> Mode<T>(
this IEnumerable<T> source,
IEqualityComparer<T> comparer = null)
{
var mode = source.GroupBy(
t => t,
(t, s) => new { Value = t, Count = s.Count() }, comparer)
.GroupBy(f => f.Count)
.OrderbyDescending(g => g.Key).FirstOrDefault();
return mode == null ? Enumerable.Empty<T>() : mode.Select(g => g.Value);
}
显然可以使用,
var mostFrequent = string.Empty.Mode();
var mostFrequent = "abbbbccd".Mode();
var mostFrequent = "aaacbbbcdddceee".Mode();
此处,mostFrequent
是IEnumerable<char>
。
答案 5 :(得分:1)
找到最简单且没有使用的内置函数
示例代码和链接
public char MostOccurringCharInString(string charString)
{
int mostOccurrence = -1;
char mostOccurringChar = ' ';
foreach (char currentChar in charString)
{
int foundCharOccreence = 0;
foreach (char charToBeMatch in charString)
{
if (currentChar == charToBeMatch)
foundCharOccreence++;
}
if (mostOccurrence < foundCharOccreence)
{
mostOccurrence = foundCharOccreence;
mostOccurringChar = currentChar;
}
}
return mostOccurringChar;
}
了解更多关于如何获得最大值以及流量的信息。
How to get max occurred character and max occurrence in string
答案 6 :(得分:0)
这是Femaref的解决方案,如果他们的Count匹配则修改为返回多个字母。它不再是单行,但仍然相当简洁,应该是相当高效的。
public static IEnumerable<char> GetMostFrequentCharacters(this string str)
{
if (string.IsNullOrEmpty(str))
return Enumerable.Empty<char>();
var groups = str.GroupBy(x => x).Select(x => new { Letter = x.Key, Count = x.Count() }).ToList();
var max = groups.Max(g2 => g2.Count);
return groups.Where(g => g.Count == max).Select(g => g.Letter);
}
答案 7 :(得分:0)
代码:
class CharCount
{
public void CountCharacter()
{
int n;
Console.WriteLine("enter the no. of elements: ");
n = Convert.ToInt32(Console.ReadLine());
char[] chararr = new char[n];
Console.WriteLine("enter the elements in array: ");
for (int i = 0; i < n; i++)
{
chararr[i] = Convert.ToChar(Console.ReadLine());
}
Dictionary<char, int> count = chararr.GroupBy(x => x).ToDictionary(g => g.Key, g => g.Count());
foreach(KeyValuePair<char, int> key in count)
{
Console.WriteLine("Occurrence of {0}: {1}",key.Key,key.Value);
}
Console.ReadLine();
}
}
答案 8 :(得分:0)
echo "$mystr"
答案 9 :(得分:0)
#simplified expression using LINQ#
string text = "abccdeeef";
int length = text.ToCharArray().GroupBy(x => x).OrderByDescending(x =>
x.Count()).First().Count();
答案 10 :(得分:0)
使用 LINQ 和 Dictionary 数据结构作为查找列表的不同方法:
var str = "abbbbccd";
var chrArr = str.ToCharArray();
Dictionary<char, int> dic = new Dictionary<char, int>();
foreach (char a in chrArr)
{
if (dic.ContainsKey(a))
dic[a]++;
else
dic.Add(a, 1);
}
int count = dic.Values.Max();
char val = dic.Where(d => d.Value == count).FirstOrDefault().Key;
答案 11 :(得分:0)
解决问题的方法有很多种。
您可以根据自己的喜好进行选择。列出其中之一。
private static void CalculateMaxCharCountUsingArray(string actualString)
{
char[] charArray = actualString.ToCharArray();
int[] arr = new int[256];
int maxCount = 0;
char maxChar = ' ';
foreach (var r in charArray)
{
arr[r] = arr[r] + 1;
if (maxCount < arr[r])
{
maxCount = arr[r];
maxChar = r;
}
}
Console.WriteLine("This character " + maxChar + " that appeared maximum times : " + maxCount);
IEnumerable<char> distinctCharArray = charArray.Distinct();
foreach(var r in distinctCharArray)
{
Console.WriteLine("This character " + r + " that appeared times " + arr[r] + " in a string");
}
}
我从下面的 link 中学到了所有这些,供您参考。