Самое распространенное слово в строке без пробелов

#c# #.net-core

#c# #.net-core

Вопрос:

У меня очень длинная строка текста, состоящая из множества слов, разделенных camelCase, например:

AedeagalAedilityAedoeagiAefaldnessAegeriidaeAeginaAeipathyAeneolithicAeolididaeAeonialAerialityAerinessAerobia

Мне нужно найти наиболее распространенное слово и количество раз, когда оно использовалось, я не знаю, как это сделать из-за отсутствия пробелов и того, что я новичок в C #.
Я перепробовал много методов, но, похоже, ни один из них не работает, я был бы очень признателен за любые ваши советы.
У меня есть репозиторий github с загружаемым файлом, и здесь уже выполнено несколько тестов: https://github.com/Imstupidpleasehelp/C-code-test

Спасибо.

Комментарии:

1. Кроме регулярного выражения может быть подход с итерацией по строке foreach (char c in text) и проверкой символа на наличие верхнего регистра if (char.IsUpper(c)) .

Ответ №1:

Вы можете попробовать запросить строку с помощью регулярных выражений и Linq:

  string source = ...

 var result = Regex
   .Matches(source, "[A-Z][a-z]*")
   .Cast<Match>()
   .Select(match => match.Value)
   .GroupBy(word => word)
   .Select(group => (word : group.Key, count : group.Count()))
   .OrderByDescending(pair => pair.count)
   .First();

 Console.Write($"{result.word} appears {result.count} time");   
  

Комментарии:

1. Большое вам спасибо, Дмитрий. У вас это выглядит так просто!

Ответ №2:

 string[] split = Regex.Split(exampleString, "(?<=[A-Za-z])(?=[A-Z][a-z])");
var result = split.GroupBy(s => s)
                  .Where(g=> g.Count()>=1 )
                  .OrderByDescending(g => g.Count())
                  .Select(g => new{ Word = g.Key, Occurrences = g.Count()});
  

результат var будет содержать пары (Слово, вхождения) для всех слов.

Если вам нужно только первое (с наибольшим количеством вхождений), используйте

 var result = split.GroupBy(s => s)
                  .Where(g=> g.Count()>=1 )
                  .OrderByDescending(g => g.Count())
                  .Select(g => new{ Word = g.Key, Occurrences = g.Count()}).First();
  

Имейте в виду, что может случиться так, что у вас есть 2 или более слов с одинаковым количеством вхождений, поэтому использование First() даст вам только одно из них.

Ответ №3:

Подход, не связанный с linq, использующий цикл for и IsUpper для разделения слов.

 string data = "AedeagalAedilityAedoeagiAefaldness";
var words = new List<string>();
var temp = new StringBuilder();

for(int i = 0;i < data.Length;i  )
{
    temp.Append(data[i]);
    if (i == data.Length-1 || char.IsUpper(data[i 1]))
    {
        words.Add(temp.ToString());
        temp.Clear();
    }
}
  

Комментарии:

1. Я предлагаю temp.Clear(); вместо temp = new StringBuilder();