From af6e010a5cd9e95e404da6912d1727ae43018c93 Mon Sep 17 00:00:00 2001 From: Aleksandr Kerov Date: Fri, 27 Feb 2026 11:37:51 +0700 Subject: [PATCH 1/7] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BD=D1=8F=D1=82=D0=B0?= =?UTF-8?q?=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D1=84=D1=80=D0=B5?= =?UTF-8?q?=D0=B9=D0=BC=D1=84=D0=BE=D1=80=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TestTask/TestTask.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TestTask/TestTask.csproj b/TestTask/TestTask.csproj index dc470b0..e4a3272 100644 --- a/TestTask/TestTask.csproj +++ b/TestTask/TestTask.csproj @@ -8,9 +8,10 @@ Exe TestTask TestTask - v4.6.1 + v4.8 512 true + AnyCPU From ea5408ee693a288c3e6367113e52ec05c178867c Mon Sep 17 00:00:00 2001 From: Aleksandr Kerov Date: Fri, 27 Feb 2026 12:03:21 +0700 Subject: [PATCH 2/7] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20ReadOnlyS?= =?UTF-8?q?tream?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Дополнительно изменен IReadOnlyStream Дополнительно изменена структура проекта Дополнены саммари Почищен gitingore --- .gitignore | 11 - TestTask/CharType.cs | 18 -- TestTask/Enums/CharType.cs | 18 ++ TestTask/IReadOnlyStream.cs | 16 -- TestTask/LetterStats.cs | 18 -- TestTask/Program.cs | 251 +++++++++--------- TestTask/ReadOnlyStream.cs | 60 ----- .../Streams/Interfaces/IReadOnlyStream.cs | 26 ++ TestTask/Streams/ReadOnlyStream.cs | 89 +++++++ TestTask/Structs/LetterStats.cs | 18 ++ TestTask/TestTask.csproj | 8 +- 11 files changed, 282 insertions(+), 251 deletions(-) delete mode 100644 TestTask/CharType.cs create mode 100644 TestTask/Enums/CharType.cs delete mode 100644 TestTask/IReadOnlyStream.cs delete mode 100644 TestTask/LetterStats.cs delete mode 100644 TestTask/ReadOnlyStream.cs create mode 100644 TestTask/Streams/Interfaces/IReadOnlyStream.cs create mode 100644 TestTask/Streams/ReadOnlyStream.cs create mode 100644 TestTask/Structs/LetterStats.cs diff --git a/.gitignore b/.gitignore index 42d3208..173c19b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,3 @@ -## .gitignore -#.gitignore - -### -## *.html -### -## !special.html -### .. -## *.[ao] - - *.suo *.user .vs/ diff --git a/TestTask/CharType.cs b/TestTask/CharType.cs deleted file mode 100644 index 899564d..0000000 --- a/TestTask/CharType.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace TestTask -{ - /// - /// Тип букв - /// - public enum CharType - { - /// - /// Гласные - /// - Vowel, - - /// - /// Согласные - /// - Consonants - } -} diff --git a/TestTask/Enums/CharType.cs b/TestTask/Enums/CharType.cs new file mode 100644 index 0000000..c1f896a --- /dev/null +++ b/TestTask/Enums/CharType.cs @@ -0,0 +1,18 @@ +namespace TestTask.Enums +{ + /// + /// Тип букв + /// + public enum CharType + { + /// + /// Гласные + /// + Vowel, + + /// + /// Согласные + /// + Consonants + } +} \ No newline at end of file diff --git a/TestTask/IReadOnlyStream.cs b/TestTask/IReadOnlyStream.cs deleted file mode 100644 index 6946745..0000000 --- a/TestTask/IReadOnlyStream.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace TestTask -{ - /// - /// Интерфейс для работы с файлом в сильно урезаном виде. - /// Умеет всего 2 вещи: прочитать символ, и перемотать стрим на начало. - /// - internal interface IReadOnlyStream - { - // TODO : Необходимо доработать данный интерфейс для обеспечения гарантированного закрытия файла, по окончанию работы с таковым! - char ReadNextChar(); - - void ResetPositionToStart(); - - bool IsEof { get; } - } -} diff --git a/TestTask/LetterStats.cs b/TestTask/LetterStats.cs deleted file mode 100644 index aa10728..0000000 --- a/TestTask/LetterStats.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace TestTask -{ - /// - /// Статистика вхождения буквы/пары букв - /// - public struct LetterStats - { - /// - /// Буква/Пара букв для учёта статистики. - /// - public string Letter; - - /// - /// Кол-во вхождений буквы/пары. - /// - public int Count; - } -} diff --git a/TestTask/Program.cs b/TestTask/Program.cs index fdf048e..f076d65 100644 --- a/TestTask/Program.cs +++ b/TestTask/Program.cs @@ -1,129 +1,132 @@ using System; using System.Collections.Generic; +using TestTask.Enums; +using TestTask.Streams; +using TestTask.Streams.Interfaces; +using TestTask.Structs; namespace TestTask { - public class Program - { - - /// - /// Программа принимает на входе 2 пути до файлов. - /// Анализирует в первом файле кол-во вхождений каждой буквы (регистрозависимо). Например А, б, Б, Г и т.д. - /// Анализирует во втором файле кол-во вхождений парных букв (не регистрозависимо). Например АА, Оо, еЕ, тт и т.д. - /// По окончанию работы - выводит данную статистику на экран. - /// - /// Первый параметр - путь до первого файла. - /// Второй параметр - путь до второго файла. - static void Main(string[] args) - { - IReadOnlyStream inputStream1 = GetInputStream(args[0]); - IReadOnlyStream inputStream2 = GetInputStream(args[1]); - - IList singleLetterStats = FillSingleLetterStats(inputStream1); - IList doubleLetterStats = FillDoubleLetterStats(inputStream2); - - RemoveCharStatsByType(singleLetterStats, CharType.Vowel); - RemoveCharStatsByType(doubleLetterStats, CharType.Consonants); - - PrintStatistic(singleLetterStats); - PrintStatistic(doubleLetterStats); - - // TODO : Необжодимо дождаться нажатия клавиши, прежде чем завершать выполнение программы. - } - - /// - /// Ф-ция возвращает экземпляр потока с уже загруженным файлом для последующего посимвольного чтения. - /// - /// Полный путь до файла для чтения - /// Поток для последующего чтения. - private static IReadOnlyStream GetInputStream(string fileFullPath) - { - return new ReadOnlyStream(fileFullPath); - } - - /// - /// Ф-ция считывающая из входящего потока все буквы, и возвращающая коллекцию статистик вхождения каждой буквы. - /// Статистика РЕГИСТРОЗАВИСИМАЯ! - /// - /// Стрим для считывания символов для последующего анализа - /// Коллекция статистик по каждой букве, что была прочитана из стрима. - private static IList FillSingleLetterStats(IReadOnlyStream stream) - { - stream.ResetPositionToStart(); - while (!stream.IsEof) - { - char c = stream.ReadNextChar(); - // TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - регистрозависимый. - } - - //return ???; - - throw new NotImplementedException(); - } - - /// - /// Ф-ция считывающая из входящего потока все буквы, и возвращающая коллекцию статистик вхождения парных букв. - /// В статистику должны попадать только пары из одинаковых букв, например АА, СС, УУ, ЕЕ и т.д. - /// Статистика - НЕ регистрозависимая! - /// - /// Стрим для считывания символов для последующего анализа - /// Коллекция статистик по каждой букве, что была прочитана из стрима. - private static IList FillDoubleLetterStats(IReadOnlyStream stream) - { - stream.ResetPositionToStart(); - while (!stream.IsEof) - { - char c = stream.ReadNextChar(); - // TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - НЕ регистрозависимый. - } - - //return ???; - - throw new NotImplementedException(); - } - - /// - /// Ф-ция перебирает все найденные буквы/парные буквы, содержащие в себе только гласные или согласные буквы. - /// (Тип букв для перебора определяется параметром charType) - /// Все найденные буквы/пары соответствующие параметру поиска - удаляются из переданной коллекции статистик. - /// - /// Коллекция со статистиками вхождения букв/пар - /// Тип букв для анализа - private static void RemoveCharStatsByType(IList letters, CharType charType) - { - // TODO : Удалить статистику по запрошенному типу букв. - switch (charType) - { - case CharType.Consonants: - break; - case CharType.Vowel: - break; - } - - } - - /// - /// Ф-ция выводит на экран полученную статистику в формате "{Буква} : {Кол-во}" - /// Каждая буква - с новой строки. - /// Выводить на экран необходимо предварительно отсортировав набор по алфавиту. - /// В конце отдельная строчка с ИТОГО, содержащая в себе общее кол-во найденных букв/пар - /// - /// Коллекция со статистикой - private static void PrintStatistic(IEnumerable letters) - { - // TODO : Выводить на экран статистику. Выводить предварительно отсортировав по алфавиту! - throw new NotImplementedException(); - } - - /// - /// Метод увеличивает счётчик вхождений по переданной структуре. - /// - /// - private static void IncStatistic(LetterStats letterStats) - { - letterStats.Count++; - } - - - } -} + public class Program + { + /// + /// Программа принимает на входе 2 пути до файлов. + /// Анализирует в первом файле кол-во вхождений каждой буквы (регистрозависимо). Например А, б, Б, Г и т.д. + /// Анализирует во втором файле кол-во вхождений парных букв (не регистрозависимо). Например АА, Оо, еЕ, тт и т.д. + /// По окончанию работы - выводит данную статистику на экран. + /// + /// Первый параметр - путь до первого файла. + /// Второй параметр - путь до второго файла. + private static void Main(string[] args) + { + IReadOnlyStream inputStream1 = GetInputStream(args[0]); + IReadOnlyStream inputStream2 = GetInputStream(args[1]); + + IList singleLetterStats = FillSingleLetterStats(inputStream1); + IList doubleLetterStats = FillDoubleLetterStats(inputStream2); + + RemoveCharStatsByType(singleLetterStats, CharType.Vowel); + RemoveCharStatsByType(doubleLetterStats, CharType.Consonants); + + PrintStatistic(singleLetterStats); + PrintStatistic(doubleLetterStats); + + // TODO : Необжодимо дождаться нажатия клавиши, прежде чем завершать выполнение программы. + } + + /// + /// Ф-ция возвращает экземпляр потока с уже загруженным файлом для последующего посимвольного чтения. + /// + /// Полный путь до файла для чтения + /// Поток для последующего чтения. + private static IReadOnlyStream GetInputStream(string fileFullPath) + { + return new ReadOnlyStream(fileFullPath); + } + + /// + /// Ф-ция считывающая из входящего потока все буквы, и возвращающая коллекцию статистик вхождения каждой буквы. + /// Статистика РЕГИСТРОЗАВИСИМАЯ! + /// + /// Стрим для считывания символов для последующего анализа + /// Коллекция статистик по каждой букве, что была прочитана из стрима. + private static IList FillSingleLetterStats(IReadOnlyStream stream) + { + stream.ResetPositionToStart(); + while (!stream.IsEof) + { + char c = stream.ReadNextChar(); + + // TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - регистрозависимый. + } + + //return ???; + + throw new NotImplementedException(); + } + + /// + /// Ф-ция считывающая из входящего потока все буквы, и возвращающая коллекцию статистик вхождения парных букв. + /// В статистику должны попадать только пары из одинаковых букв, например АА, СС, УУ, ЕЕ и т.д. + /// Статистика - НЕ регистрозависимая! + /// + /// Стрим для считывания символов для последующего анализа + /// Коллекция статистик по каждой букве, что была прочитана из стрима. + private static IList FillDoubleLetterStats(IReadOnlyStream stream) + { + stream.ResetPositionToStart(); + while (!stream.IsEof) + { + char c = stream.ReadNextChar(); + + // TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - НЕ регистрозависимый. + } + + //return ???; + + throw new NotImplementedException(); + } + + /// + /// Ф-ция перебирает все найденные буквы/парные буквы, содержащие в себе только гласные или согласные буквы. + /// (Тип букв для перебора определяется параметром charType) + /// Все найденные буквы/пары соответствующие параметру поиска - удаляются из переданной коллекции статистик. + /// + /// Коллекция со статистиками вхождения букв/пар + /// Тип букв для анализа + private static void RemoveCharStatsByType(IList letters, CharType charType) + { + // TODO : Удалить статистику по запрошенному типу букв. + switch (charType) + { + case CharType.Consonants: + break; + + case CharType.Vowel: + break; + } + } + + /// + /// Ф-ция выводит на экран полученную статистику в формате "{Буква} : {Кол-во}" + /// Каждая буква - с новой строки. + /// Выводить на экран необходимо предварительно отсортировав набор по алфавиту. + /// В конце отдельная строчка с ИТОГО, содержащая в себе общее кол-во найденных букв/пар + /// + /// Коллекция со статистикой + private static void PrintStatistic(IEnumerable letters) + { + // TODO : Выводить на экран статистику. Выводить предварительно отсортировав по алфавиту! + throw new NotImplementedException(); + } + + /// + /// Метод увеличивает счётчик вхождений по переданной структуре. + /// + /// + private static void IncStatistic(LetterStats letterStats) + { + letterStats.Count++; + } + } +} \ No newline at end of file diff --git a/TestTask/ReadOnlyStream.cs b/TestTask/ReadOnlyStream.cs deleted file mode 100644 index a51a61e..0000000 --- a/TestTask/ReadOnlyStream.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.IO; - -namespace TestTask -{ - public class ReadOnlyStream : IReadOnlyStream - { - private Stream _localStream; - - /// - /// Конструктор класса. - /// Т.к. происходит прямая работа с файлом, необходимо - /// обеспечить ГАРАНТИРОВАННОЕ закрытие файла после окончания работы с таковым! - /// - /// Полный путь до файла для чтения - public ReadOnlyStream(string fileFullPath) - { - IsEof = true; - - // TODO : Заменить на создание реального стрима для чтения файла! - _localStream = null; - } - - /// - /// Флаг окончания файла. - /// - public bool IsEof - { - get; // TODO : Заполнять данный флаг при достижении конца файла/стрима при чтении - private set; - } - - /// - /// Ф-ция чтения следующего символа из потока. - /// Если произведена попытка прочитать символ после достижения конца файла, метод - /// должен бросать соответствующее исключение - /// - /// Считанный символ. - public char ReadNextChar() - { - // TODO : Необходимо считать очередной символ из _localStream - throw new NotImplementedException(); - } - - /// - /// Сбрасывает текущую позицию потока на начало. - /// - public void ResetPositionToStart() - { - if (_localStream == null) - { - IsEof = true; - return; - } - - _localStream.Position = 0; - IsEof = false; - } - } -} diff --git a/TestTask/Streams/Interfaces/IReadOnlyStream.cs b/TestTask/Streams/Interfaces/IReadOnlyStream.cs new file mode 100644 index 0000000..fdc33b1 --- /dev/null +++ b/TestTask/Streams/Interfaces/IReadOnlyStream.cs @@ -0,0 +1,26 @@ +namespace TestTask.Streams.Interfaces +{ + using System; + + /// + /// Интерфейс для работы с файлом в сильно урезаном виде. + /// + internal interface IReadOnlyStream : IDisposable + { + /// + /// Читает следующий символ из потока. + /// + /// Считанный символ. + char ReadNextChar(); + + /// + /// Сбрасывает текущую позицию потока на начало. + /// + void ResetPositionToStart(); + + /// + /// Флаг окончания файла. + /// + bool IsEof { get; } + } +} \ No newline at end of file diff --git a/TestTask/Streams/ReadOnlyStream.cs b/TestTask/Streams/ReadOnlyStream.cs new file mode 100644 index 0000000..5523baf --- /dev/null +++ b/TestTask/Streams/ReadOnlyStream.cs @@ -0,0 +1,89 @@ +using System.IO; +using System.Text; +using TestTask.Streams.Interfaces; + +namespace TestTask.Streams +{ + /// + /// Кастомный класс потока для чтения текстовых файлов. + /// + public class ReadOnlyStream : IReadOnlyStream + { + #region Fields + + /// + /// Поток для чтения файла. + /// + private StreamReader _streamReader; + + #endregion Fields + + #region Properties + + /// + public bool IsEof + { + get; + private set; + } + + #endregion Properties + + #region Public Constructors + + /// + /// Конструктор класса. + /// + /// Полный путь до файла для чтения + public ReadOnlyStream(string fileFullPath) : this(fileFullPath, Encoding.UTF8) + { + } + + /// + /// Конструктор класса. + /// + /// Полный путь до файла для чтения. + /// Кодировка. + public ReadOnlyStream(string fileFullPath, Encoding encoding) + { + var localStream = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read); + _streamReader = new StreamReader(localStream, encoding); + } + + #endregion Public Constructors + + #region Public Methods + + /// + public void Dispose() + { + _streamReader?.Dispose(); + _streamReader = null; + } + + /// + public char ReadNextChar() + { + char letter = (char)_streamReader.Read(); + + if (_streamReader.EndOfStream) + IsEof = true; + + return letter; + } + + /// + public void ResetPositionToStart() + { + if (_streamReader != null) + { + _streamReader.DiscardBufferedData(); + _streamReader.BaseStream.Position = 0; + } + + IsEof = false; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/TestTask/Structs/LetterStats.cs b/TestTask/Structs/LetterStats.cs new file mode 100644 index 0000000..9b9604f --- /dev/null +++ b/TestTask/Structs/LetterStats.cs @@ -0,0 +1,18 @@ +namespace TestTask.Structs +{ + /// + /// Статистика вхождения буквы/пары букв + /// + public struct LetterStats + { + /// + /// Буква/Пара букв для учёта статистики. + /// + public string Letter; + + /// + /// Кол-во вхождений буквы/пары. + /// + public int Count; + } +} \ No newline at end of file diff --git a/TestTask/TestTask.csproj b/TestTask/TestTask.csproj index e4a3272..7a99941 100644 --- a/TestTask/TestTask.csproj +++ b/TestTask/TestTask.csproj @@ -43,12 +43,12 @@ - - - + + + - + \ No newline at end of file From fe261c925a985d7a1a10116a9af6098b9a2b2986 Mon Sep 17 00:00:00 2001 From: Aleksandr Kerov Date: Fri, 27 Feb 2026 12:49:25 +0700 Subject: [PATCH 3/7] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=BD=D0=BE=20=D0=B7=D0=B0=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D1=82=D0=B0=D1=82=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TestTask/Helpers/FillLetterStatsHelper.cs | 98 +++++++++++++++++++++ TestTask/Program.cs | 101 +++++++--------------- TestTask/Structs/LetterStats.cs | 4 +- TestTask/TestTask.csproj | 1 + 4 files changed, 131 insertions(+), 73 deletions(-) create mode 100644 TestTask/Helpers/FillLetterStatsHelper.cs diff --git a/TestTask/Helpers/FillLetterStatsHelper.cs b/TestTask/Helpers/FillLetterStatsHelper.cs new file mode 100644 index 0000000..3c53702 --- /dev/null +++ b/TestTask/Helpers/FillLetterStatsHelper.cs @@ -0,0 +1,98 @@ +namespace TestTask.Helpers +{ + using System.Collections.Generic; + using TestTask.Streams.Interfaces; + using TestTask.Structs; + + /// + /// Хелпер для составления статистики букв. + /// + internal static class FillLetterStatsHelper + { + #region Public Methods + + /// + /// Считывает из входящего потока все буквы, и возвращающает коллекцию статистик вхождения парных букв. + /// + /// Стрим для считывания символов для последующего анализа + /// Коллекция статистик по каждой букве, что была прочитана из стрима. + /// + /// В статистику должны попадать только пары из одинаковых букв, например АА, СС, УУ, ЕЕ и т.д. + /// Статистика - НЕ регистрозависимая! + /// + public static Dictionary FillDoubleLetterStats(IReadOnlyStream stream) + { + stream.ResetPositionToStart(); + + var statsByLetter = new Dictionary(); + char? prevLetter = null; + + while (!stream.IsEof) + { + char c = stream.ReadNextChar(); + + // В статистику идут только буквы + if (!char.IsLetter(c)) + { + prevLetter = null; // разрываем последовательность + continue; + } + + char letter = char.ToLowerInvariant(c); // НЕ регистрозависимо + + // Если текущая буква равна предыдущей — это парная буква (AA, CC, ...) + if (prevLetter.HasValue && prevLetter.Value == letter) + { + // ВАЖНО: инкрементим статистику именно по букве + if (statsByLetter.TryGetValue(letter, out LetterStats stats)) + { + stats.Count++; + statsByLetter[letter] = stats; // обязательно вернуть обратно + } + else + { + statsByLetter[letter] = new LetterStats { Count = 1, Letter = $"{letter}{letter}" }; + } + } + + prevLetter = letter; + } + + return statsByLetter; + } + + /// + /// Считывает из входящего потока все буквы, и возвращающает коллекцию статистик вхождения каждой буквы. + /// + /// Стрим для считывания символов для последующего анализа + /// Коллекция статистик по каждой букве, что была прочитана из стрима. + /// Статистика РЕГИСТРОЗАВИСИМАЯ! + public static Dictionary FillSingleLetterStats(IReadOnlyStream stream) + { + stream.ResetPositionToStart(); + Dictionary statsByLetter = new Dictionary(); + + while (!stream.IsEof) + { + char letter = stream.ReadNextChar(); + + if (char.IsLetter(letter)) + { + if (statsByLetter.TryGetValue(letter, out LetterStats stats)) + { + stats.Count++; + statsByLetter[letter] = stats; // обязательно вернуть обратно + } + else + { + statsByLetter[letter] = new LetterStats { Count = 1, Letter = letter.ToString() }; + } + } + } + + return statsByLetter; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/TestTask/Program.cs b/TestTask/Program.cs index f076d65..46350e8 100644 --- a/TestTask/Program.cs +++ b/TestTask/Program.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using TestTask.Enums; +using TestTask.Helpers; using TestTask.Streams; using TestTask.Streams.Interfaces; using TestTask.Structs; @@ -19,72 +20,39 @@ public class Program /// Второй параметр - путь до второго файла. private static void Main(string[] args) { - IReadOnlyStream inputStream1 = GetInputStream(args[0]); - IReadOnlyStream inputStream2 = GetInputStream(args[1]); - - IList singleLetterStats = FillSingleLetterStats(inputStream1); - IList doubleLetterStats = FillDoubleLetterStats(inputStream2); - - RemoveCharStatsByType(singleLetterStats, CharType.Vowel); - RemoveCharStatsByType(doubleLetterStats, CharType.Consonants); - - PrintStatistic(singleLetterStats); - PrintStatistic(doubleLetterStats); - - // TODO : Необжодимо дождаться нажатия клавиши, прежде чем завершать выполнение программы. - } - - /// - /// Ф-ция возвращает экземпляр потока с уже загруженным файлом для последующего посимвольного чтения. - /// - /// Полный путь до файла для чтения - /// Поток для последующего чтения. - private static IReadOnlyStream GetInputStream(string fileFullPath) - { - return new ReadOnlyStream(fileFullPath); - } - - /// - /// Ф-ция считывающая из входящего потока все буквы, и возвращающая коллекцию статистик вхождения каждой буквы. - /// Статистика РЕГИСТРОЗАВИСИМАЯ! - /// - /// Стрим для считывания символов для последующего анализа - /// Коллекция статистик по каждой букве, что была прочитана из стрима. - private static IList FillSingleLetterStats(IReadOnlyStream stream) - { - stream.ResetPositionToStart(); - while (!stream.IsEof) + try { - char c = stream.ReadNextChar(); - - // TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - регистрозависимый. + if (args.Length != 2) + { + throw new ArgumentException("Входных аргументов должно быть два ", nameof(args)); + } + + Dictionary singleLetterStats = null; + Dictionary doubleLetterStats = null; + + using (IReadOnlyStream inputStream1 = new ReadOnlyStream(args[0])) + { + singleLetterStats = FillLetterStatsHelper.FillSingleLetterStats(inputStream1); + } + using (IReadOnlyStream inputStream2 = new ReadOnlyStream(args[1])) + { + doubleLetterStats = FillLetterStatsHelper.FillDoubleLetterStats(inputStream2); + } + + //RemoveCharStatsByType(singleLetterStats, CharType.Vowel); + //RemoveCharStatsByType(doubleLetterStats, CharType.Consonants); + + //PrintStatistic(singleLetterStats); + //PrintStatistic(doubleLetterStats); } - - //return ???; - - throw new NotImplementedException(); - } - - /// - /// Ф-ция считывающая из входящего потока все буквы, и возвращающая коллекцию статистик вхождения парных букв. - /// В статистику должны попадать только пары из одинаковых букв, например АА, СС, УУ, ЕЕ и т.д. - /// Статистика - НЕ регистрозависимая! - /// - /// Стрим для считывания символов для последующего анализа - /// Коллекция статистик по каждой букве, что была прочитана из стрима. - private static IList FillDoubleLetterStats(IReadOnlyStream stream) - { - stream.ResetPositionToStart(); - while (!stream.IsEof) + catch (Exception ex) { - char c = stream.ReadNextChar(); - - // TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - НЕ регистрозависимый. + Console.WriteLine(ex.Message); + } + finally + { + Console.ReadKey(); } - - //return ???; - - throw new NotImplementedException(); } /// @@ -119,14 +87,5 @@ private static void PrintStatistic(IEnumerable letters) // TODO : Выводить на экран статистику. Выводить предварительно отсортировав по алфавиту! throw new NotImplementedException(); } - - /// - /// Метод увеличивает счётчик вхождений по переданной структуре. - /// - /// - private static void IncStatistic(LetterStats letterStats) - { - letterStats.Count++; - } } } \ No newline at end of file diff --git a/TestTask/Structs/LetterStats.cs b/TestTask/Structs/LetterStats.cs index 9b9604f..4c666d0 100644 --- a/TestTask/Structs/LetterStats.cs +++ b/TestTask/Structs/LetterStats.cs @@ -8,11 +8,11 @@ public struct LetterStats /// /// Буква/Пара букв для учёта статистики. /// - public string Letter; + public string Letter { get; set; } /// /// Кол-во вхождений буквы/пары. /// - public int Count; + public int Count { get; set; } } } \ No newline at end of file diff --git a/TestTask/TestTask.csproj b/TestTask/TestTask.csproj index 7a99941..07ad419 100644 --- a/TestTask/TestTask.csproj +++ b/TestTask/TestTask.csproj @@ -44,6 +44,7 @@ + From da24ac668f7487d765c9b14796e7205fb5a69bc5 Mon Sep 17 00:00:00 2001 From: Aleksandr Kerov Date: Fri, 27 Feb 2026 12:55:04 +0700 Subject: [PATCH 4/7] =?UTF-8?q?=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B3=D0=BB=D0=B0=D1=81=D0=BD=D1=83=D1=8E=20=D0=B1?= =?UTF-8?q?=D1=83=D0=BA=D0=B2=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Реализацияв классе CharExtension --- TestTask/Helpers/Extensions/CharExtension.cs | 74 ++++++++++++++++++++ TestTask/TestTask.csproj | 1 + 2 files changed, 75 insertions(+) create mode 100644 TestTask/Helpers/Extensions/CharExtension.cs diff --git a/TestTask/Helpers/Extensions/CharExtension.cs b/TestTask/Helpers/Extensions/CharExtension.cs new file mode 100644 index 0000000..3ca4ae0 --- /dev/null +++ b/TestTask/Helpers/Extensions/CharExtension.cs @@ -0,0 +1,74 @@ +namespace TestTask.Helpers.Extensions +{ + /// + /// Расширение для char. + /// + internal static class CharExtension + { + #region Public Methods + + /// + /// Проверяет символ английская ли глассная буква? + /// + /// Входной символ. + /// Английская глассная буква? + public static bool IsEnglishVowel(this char value) + { + value = char.ToLowerInvariant(value); + + switch (value) + { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + return true; + + default: + return false; + } + } + + /// + /// Проверяет символ русская ли глассная буква? + /// + /// Входной символ. + /// Русская глассная буква? + public static bool IsRussianVowel(this char value) + { + value = char.ToLowerInvariant(value); + + switch (value) + { + case 'а': + case 'е': + case 'ё': + case 'и': + case 'о': + case 'у': + case 'ы': + case 'э': + case 'ю': + case 'я': + return true; + + default: + return false; + } + } + + /// + /// Проверяет символ глассная ли буква? + /// + /// Входной символ. + /// Глассная буква? + /// Проверка русского и английского алфовита. + public static bool IsVowel(this char value) + { + return IsRussianVowel(value) || IsEnglishVowel(value); + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/TestTask/TestTask.csproj b/TestTask/TestTask.csproj index 07ad419..3f241d7 100644 --- a/TestTask/TestTask.csproj +++ b/TestTask/TestTask.csproj @@ -44,6 +44,7 @@ + From 6b7bdfe988b75a1d4996d3b0aec555fc2808f46f Mon Sep 17 00:00:00 2001 From: Aleksandr Kerov Date: Fri, 27 Feb 2026 13:40:22 +0700 Subject: [PATCH 5/7] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B8=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TestTask/Helpers/FillLetterStatsHelper.cs | 9 ++-- TestTask/Helpers/FilterCharStats.cs | 47 ++++++++++++++++++++ TestTask/Program.cs | 52 +++++++++++------------ TestTask/TestTask.csproj | 1 + 4 files changed, 78 insertions(+), 31 deletions(-) create mode 100644 TestTask/Helpers/FilterCharStats.cs diff --git a/TestTask/Helpers/FillLetterStatsHelper.cs b/TestTask/Helpers/FillLetterStatsHelper.cs index 3c53702..f822aea 100644 --- a/TestTask/Helpers/FillLetterStatsHelper.cs +++ b/TestTask/Helpers/FillLetterStatsHelper.cs @@ -29,16 +29,17 @@ public static Dictionary FillDoubleLetterStats(IReadOnlyStrea while (!stream.IsEof) { - char c = stream.ReadNextChar(); + char originalLetter = stream.ReadNextChar(); // В статистику идут только буквы - if (!char.IsLetter(c)) + if (!char.IsLetter(originalLetter)) { - prevLetter = null; // разрываем последовательность + prevLetter = null; + continue; } - char letter = char.ToLowerInvariant(c); // НЕ регистрозависимо + char letter = char.ToUpper(originalLetter); // НЕ регистрозависимо // Если текущая буква равна предыдущей — это парная буква (AA, CC, ...) if (prevLetter.HasValue && prevLetter.Value == letter) diff --git a/TestTask/Helpers/FilterCharStats.cs b/TestTask/Helpers/FilterCharStats.cs new file mode 100644 index 0000000..132b31e --- /dev/null +++ b/TestTask/Helpers/FilterCharStats.cs @@ -0,0 +1,47 @@ +namespace TestTask.Helpers +{ + using System.Collections.Generic; + using System.Linq; + using TestTask.Enums; + using TestTask.Helpers.Extensions; + using TestTask.Structs; + + /// + /// Класс для фильтрации статистики букв. + /// + internal static class FilterCharStats + { + /// + /// Фильтруются все найденные буквы/парные буквы, содержащие в себе только гласные или согласные буквы. + /// (Тип букв для перебора определяется параметром charType) + /// Все найденные буквы/пары соответствующие параметру поиска - удаляются из переданной коллекции статистик. + /// + /// Коллекция со статистиками вхождения букв/пар + /// Тип букв для анализа + public static void RemoveCharStatsByType(Dictionary letters, CharType charType) + { + List list = letters.Select(x => x.Key).ToList(); + + foreach (char value in list) + { + switch (charType) + { + case CharType.Consonants: + + if (!value.IsVowel()) + { + letters.Remove(value); + } + break; + + case CharType.Vowel: + if (value.IsVowel()) + { + letters.Remove(value); + } + break; + } + } + } + } +} \ No newline at end of file diff --git a/TestTask/Program.cs b/TestTask/Program.cs index 46350e8..48a9426 100644 --- a/TestTask/Program.cs +++ b/TestTask/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using TestTask.Enums; using TestTask.Helpers; using TestTask.Streams; @@ -8,6 +9,9 @@ namespace TestTask { + /// + /// Корневой класс программы. + /// public class Program { /// @@ -39,11 +43,11 @@ private static void Main(string[] args) doubleLetterStats = FillLetterStatsHelper.FillDoubleLetterStats(inputStream2); } - //RemoveCharStatsByType(singleLetterStats, CharType.Vowel); - //RemoveCharStatsByType(doubleLetterStats, CharType.Consonants); + FilterCharStats.RemoveCharStatsByType(singleLetterStats, CharType.Vowel); + FilterCharStats.RemoveCharStatsByType(doubleLetterStats, CharType.Consonants); - //PrintStatistic(singleLetterStats); - //PrintStatistic(doubleLetterStats); + PrintStatistic(singleLetterStats); + PrintStatistic(doubleLetterStats); } catch (Exception ex) { @@ -56,36 +60,30 @@ private static void Main(string[] args) } /// - /// Ф-ция перебирает все найденные буквы/парные буквы, содержащие в себе только гласные или согласные буквы. - /// (Тип букв для перебора определяется параметром charType) - /// Все найденные буквы/пары соответствующие параметру поиска - удаляются из переданной коллекции статистик. - /// - /// Коллекция со статистиками вхождения букв/пар - /// Тип букв для анализа - private static void RemoveCharStatsByType(IList letters, CharType charType) - { - // TODO : Удалить статистику по запрошенному типу букв. - switch (charType) - { - case CharType.Consonants: - break; - - case CharType.Vowel: - break; - } - } - - /// - /// Ф-ция выводит на экран полученную статистику в формате "{Буква} : {Кол-во}" + /// Выводит на экран полученную статистику в формате "{Буква} : {Кол-во}" /// Каждая буква - с новой строки. /// Выводить на экран необходимо предварительно отсортировав набор по алфавиту. /// В конце отдельная строчка с ИТОГО, содержащая в себе общее кол-во найденных букв/пар /// /// Коллекция со статистикой - private static void PrintStatistic(IEnumerable letters) + private static void PrintStatistic(Dictionary letters) { // TODO : Выводить на экран статистику. Выводить предварительно отсортировав по алфавиту! - throw new NotImplementedException(); + IEnumerable> orderCollection = letters.OrderBy(x => x.Key).Select(x => x); + int uniqueCount = 0; + int generalCount = 0; + + foreach (KeyValuePair item in orderCollection) + { + Console.WriteLine(string.Format("{0} : {1}", item.Value.Letter, item.Value.Count)); + + uniqueCount++; + generalCount += item.Value.Count; + } + + Console.WriteLine("ИТОГО уникальных: " + uniqueCount); + Console.WriteLine("ИТОГО сумма: " + generalCount); + Console.WriteLine(); } } } \ No newline at end of file diff --git a/TestTask/TestTask.csproj b/TestTask/TestTask.csproj index 3f241d7..765e16f 100644 --- a/TestTask/TestTask.csproj +++ b/TestTask/TestTask.csproj @@ -46,6 +46,7 @@ + From 7b26fae669eccc0919ade6fb1c005c1e956359ad Mon Sep 17 00:00:00 2001 From: Aleksandr Kerov Date: Fri, 27 Feb 2026 13:42:33 +0700 Subject: [PATCH 6/7] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BA=D0=BE=D0=BC=D0=B5=D0=BD=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit У вывода --- TestTask/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TestTask/Program.cs b/TestTask/Program.cs index 48a9426..6897b46 100644 --- a/TestTask/Program.cs +++ b/TestTask/Program.cs @@ -81,6 +81,7 @@ private static void PrintStatistic(Dictionary letters) generalCount += item.Value.Count; } + //По задаче не понял что имелось в виду под ИТОГО. Console.WriteLine("ИТОГО уникальных: " + uniqueCount); Console.WriteLine("ИТОГО сумма: " + generalCount); Console.WriteLine(); From ef1394846524d57a16ce0bfdedf73b8ef788e954 Mon Sep 17 00:00:00 2001 From: Aleksandr Kerov Date: Fri, 27 Feb 2026 13:54:24 +0700 Subject: [PATCH 7/7] Create changelog.md --- changelog.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..c339241 --- /dev/null +++ b/changelog.md @@ -0,0 +1,5 @@ +[27.02.2026] +Update - реализация тестового задания: +- Реализаци потока чтения. +- Реализация заполнения фильтрация и вывода статистики. +- Мелки правки ошибок. \ No newline at end of file