查找字符串中出现次数最多的字符?

发布于 2024-10-18 10:52:22 字数 172 浏览 2 评论 0 原文

例如,我有一个字符串:

"abbbbccd"

b 出现次数最多。使用 C++ 时,处理此问题的最简单方法是将每个字符插入到 map 中。我必须在 C# 中做同样的事情吗?有没有一种使用 LINQ 的优雅方法?

For example, I have a string:

"abbbbccd"

b has the most occurrences. When using C++, the easiest way to handle this is inserting each character into a map<>. Do I have to do the same thing in C#? Is there an elegant way to do it using LINQ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

秉烛思 2024-10-25 10:52:22
input.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key

注意:

input.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key

Notes:

软甜啾 2024-10-25 10:52:22

这是因为有人要求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 版本。它将提取配对的“最佳”(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);
}

This because someone asked for a 2.0 version, so no 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);
    }
}

Instead this for the LINQ version. It will extract paired "bests" (aaaabbbb == a, b). It WON'T work if 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);
}
情绪少女 2024-10-25 10:52:22
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);
}
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);
}
澜川若宁 2024-10-25 10:52:22

受斯蒂芬的回答启发,几乎相同:

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的 回答(发布版本,调试器分离,哦,是的)

来源=“”;

迭代次数 = 1000000

结果:

this - 280 ms
Jodrell's - 900 ms

来源=“aabc”;

迭代次数 = 1000000

结果:

this - 1800 ms
Jodrell's - 3200 ms

源 = 相当大的字符串 - 3500+ 字符

迭代次数 = 10000

结果:

this - 3200 ms
Jodrell's - 3000 ms

Inspired from Stephen's answer, almost the same:

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 }

Update: Did a quick benchmarking of this answer vs Jodrell's answer (release build, debugger detached, oh yes)

source = "";

iterations = 1000000

result:

this - 280 ms
Jodrell's - 900 ms

source = "aabc";

iterations = 1000000

result:

this - 1800 ms
Jodrell's - 3200 ms

source = fairly large string - 3500+ char

iterations = 10000

result:

this - 3200 ms
Jodrell's - 3000 ms
╄→承喏 2024-10-25 10:52:22

编辑3

这是我的最后一个答案,我认为它(只是)遮蔽了Nawfal在较长序列上的性能。

然而,鉴于 Nawfal 的答案 的复杂性降低,并且其更通用的性能,特别是与问题相关,我会选择那个。

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();

请注意,mostFrequentKeyValuePair>


如果您愿意,您可以将其简化为另一个扩展,

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

EDIT 3

Here is my last answer which I think (just) shades Nawfal's for performance on longer sequences.

However, given the reduced complexity of Nawfal's answer, and its more universal performance, especially in relation to the question, I'd choose that.

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);
}

EDIT 2


EDIT



If you want an efficient generic solution, that accounts for the fact that multiple items could have the same frequency, start with this extension,

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);
}

This extension works in all of the following scenarios

var mostFrequent = string.Empty.Frequency().FirstOrDefault();

var mostFrequent = "abbbbccd".Frequency().First();

or,

var mostFrequent = "aaacbbbcdddceee".Frequency().First();

Note that mostFrequent is a KeyValuePair<int, IEnumerable<char>>.


If so minded you could simplify this to another extension,

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);
}

which obviously could be used thus,

var mostFrequent = string.Empty.Mode();

var mostFrequent = "abbbbccd".Mode();

var mostFrequent = "aaacbbbcdddceee".Mode();

here, mostFrequent is an IEnumerable<char>.

温柔一刀 2024-10-25 10:52:22

找到最简单且没有内置函数的

示例代码和链接

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;
}

了解有关如何获得最大出现次数以及流程的更多信息。

如何获取字符串中出现的最大字符数和最大出现次数

Find the simplest and without built in function used

sample code and links

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;
}

Know more about how to get max occurrence and what is the flow.

How to get max occurred character and max occurrence in string

神回复 2024-10-25 10:52:22
#simplified expression using LINQ#
string text = "abccdeeef";
int length = text.ToCharArray().GroupBy(x => x).OrderByDescending(x => 
x.Count()).First().Count();
#simplified expression using LINQ#
string text = "abccdeeef";
int length = text.ToCharArray().GroupBy(x => x).OrderByDescending(x => 
x.Count()).First().Count();
本王不退位尔等都是臣 2024-10-25 10:52:22

有许多不同的方法可以解决这个问题。

  1. Linq
  2. 词典
  3. 使用系统。

您可以根据自己的喜好进行选择。列举其中之一。

  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");

            }
        }

我从下面的链接中了解到了所有这些内容,供您参考。

There are many different ways to solve the problem.

  1. Linq
  2. Dictionary
  3. Using system.

You can choose based on your preferences. Listing one of it.

  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");

            }
        }

I learned all of them from the below link for your reference.

你的心境我的脸 2024-10-25 10:52:22

代码:

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();
    }
}

Code:

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();
    }
}
扭转时空 2024-10-25 10:52:22
        //find most occuring character and count from below string

        string totest = "abcda12Zernn111y";

        string maxOccuringCharacter = "";
        int maxOccurence = 0;string currentLoopCharacter = ""; string updatedStringToTest = "";int cnt = 0;

        for (int i = 0; i < totest.Length; i++)
        {
            currentLoopCharacter = totest[i].ToString();
            updatedStringToTest = totest.Replace(currentLoopCharacter, "");

            cnt = totest.Length - updatedStringToTest.Length;

            if (cnt > maxOccurence)
            {
                maxOccuringCharacter = currentLoopCharacter;
                maxOccurence = cnt;
            }

            totest = updatedStringToTest;
        }

        Console.WriteLine("The most occuring character is {0} and occurence was {1}", maxOccuringCharacter, maxOccurence.ToString());
        Console.ReadLine();
        //find most occuring character and count from below string

        string totest = "abcda12Zernn111y";

        string maxOccuringCharacter = "";
        int maxOccurence = 0;string currentLoopCharacter = ""; string updatedStringToTest = "";int cnt = 0;

        for (int i = 0; i < totest.Length; i++)
        {
            currentLoopCharacter = totest[i].ToString();
            updatedStringToTest = totest.Replace(currentLoopCharacter, "");

            cnt = totest.Length - updatedStringToTest.Length;

            if (cnt > maxOccurence)
            {
                maxOccuringCharacter = currentLoopCharacter;
                maxOccurence = cnt;
            }

            totest = updatedStringToTest;
        }

        Console.WriteLine("The most occuring character is {0} and occurence was {1}", maxOccuringCharacter, maxOccurence.ToString());
        Console.ReadLine();
余罪 2024-10-25 10:52:22

这是 Femaref 的解决方案,经过修改后,如果多个字母的计数匹配,则返回多个字母。它不再是一句台词,但仍然相当简洁,并且应该具有相当的性能。

    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);
    }

This is Femaref's solution modified to return multiple letters if their Count matches. Its no longer a one-liner but still reasonably concise and should be fairly performant.

    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);
    }
像你 2024-10-25 10:52:22

使用 LINQ 和字典数据结构作为查找列表的不同方法:

        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;

A different approach using LINQ and a Dictionary data structure as a lookup list:

        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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文