C# Обработка текста. Как оптимизировать код и сделать его читабельнее, красивее?

Как оптимизировать код? Можно ли сделать быстрее? Можно ли придумать n^2 алгоритм для функции ParseSentences? Есть ли другой способ записать предложения более логичный и простой чем GetSentencesWithWords? Правильно ли выбраны типы переменных или можно что-то выбрать более подходящее? Ищу все свои косяки

Метод ParseSentences должен делать следующее: Разделять текст на предложения, а предложения на слова.

  1. Считайте, что слова состоят только из букв (используйте метод char.IsLetter) или символа апострофа ' и отделены друг от друга любыми другими символами.

  2. Предложения состоят из слов и отделены друг от друга одним из следующих символов .!?;:() Приводить символы каждого слова в нижний регистр.

  3. Пропускать предложения, в которых не оказалось слов.

Метод должен возвращать список предложений, где каждое предложение — это список из одного или более слов в нижнем регистре.


        using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApp11
{
    public static class SentencesParserTask
    {
        static void Main(string[] args)
        {
            var text1 = "B.C.D";
            Console.WriteLine("The origin string: \n" + text1);
            var sentences = new List<List<string>>();
                sentences = ParseSentences(text1);
            Console.Write("The result string: ");
            foreach (var sentence in sentences)
            {
                foreach (var word in sentence)
                {
                    Console.Write(word + " ");
                }
            }

            Console.WriteLine("\nexpected result: b c d");

            var text2 = "b;\tc;\rd;\ne;\r\nf;\r\n\r\ng";

            sentences = ParseSentences(text2);
            Console.WriteLine("\n\nThe origin string: \n" + text2);
            Console.Write("The result string: ");

            foreach (var sentence in sentences)
            {
                foreach (var word in sentence)
                {
                    Console.Write(word + " ");
                }
            }

            Console.Write("\nexpected result: b c d e f g");

            Console.ReadLine();
        }

        public static List<List<string>> ParseSentences(string text)
        {
            var wordsList = new List<List<string>>();
            List<string> actualSentences = GetSentencesWithWords(text);
            for (int j = 0; j < actualSentences.Count; j++)
            {
                wordsList.Add(new List<string>());
                for (int i = 0; i < actualSentences[j].Length; i++)
                {
                    StringBuilder word = new StringBuilder("");
                    while (i < actualSentences[j].Length &&
                    (char.IsLetter(actualSentences[j][i]) || actualSentences[j][i] == '\''))
                    {
                        word.Append(char.ToLower(actualSentences[j][i]));
                        i++;
                    }
                    if (!string.IsNullOrEmpty(word.ToString()))
                        wordsList[j].Add(word.ToString());
                }
            }
            return wordsList;
        }

        public static List<string> GetSentencesWithWords(string text)
        {
            List<string> resultSentences = new List<string>();
            char[] separators = new char[] { ';', ':', '.', '!', '?', '(', ')' };
            string[] sentences;
            sentences = text.Split(separators);
            for (int i = 0; i < sentences.Length; i++)
            {
                foreach (var symbol in sentences[i])
                    if (char.IsLetter(symbol) || symbol == '\'')
                    {
                        resultSentences.Add(sentences[i]);
                        break;
                    }
            }
            return resultSentences;
        }
    }
}


Ответы (1 шт):

Автор решения: aepot

Вот вам даже меньше, чем N ^ 2, шаблон проектирования "конечный автомат".

Специально избегал использования Linq

static List<List<string>> ParseSentences(string text)
{
    var result = new List<List<string>>();

    List<string> sentence = new List<string>();
    StringBuilder sb = new StringBuilder();
    foreach (char c in text)
    {
        if (char.IsLetter(c) || c == '\'')
            sb.Append(char.ToLower(c));
        else
        {
            if (sb.Length > 0)
            {
                sentence.Add(sb.ToString());
                sb.Clear();
            }

            if (";:.!?()".Contains(c) && sentence.Count > 0)
            {
                result.Add(sentence);
                sentence = new List<string>();
            }
        }
    }
    if (sb.Length > 0)
        sentence.Add(sb.ToString());
    if (sentence.Count > 0)
        result.Add(sentence);

    return result;
}
→ Ссылка