C# Обработка текста. Как оптимизировать код и сделать его читабельнее, красивее?
Как оптимизировать код? Можно ли сделать быстрее? Можно ли придумать n^2 алгоритм для функции ParseSentences? Есть ли другой способ записать предложения более логичный и простой чем GetSentencesWithWords? Правильно ли выбраны типы переменных или можно что-то выбрать более подходящее? Ищу все свои косяки
Метод
ParseSentencesдолжен делать следующее: Разделять текст на предложения, а предложения на слова.
Считайте, что слова состоят только из букв (используйте метод
char.IsLetter) или символа апострофа'и отделены друг от друга любыми другими символами.Предложения состоят из слов и отделены друг от друга одним из следующих символов
.!?;:()Приводить символы каждого слова в нижний регистр.Пропускать предложения, в которых не оказалось слов.
Метод должен возвращать список предложений, где каждое предложение — это список из одного или более слов в нижнем регистре.
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 шт):
Вот вам даже меньше, чем 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;
}