Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions TestTask/IReadOnlyStream.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
namespace TestTask
using System;

namespace TestTask
{
/// <summary>
/// Интерфейс для работы с файлом в сильно урезаном виде.
/// Умеет всего 2 вещи: прочитать символ, и перемотать стрим на начало.
/// </summary>
internal interface IReadOnlyStream
internal interface IReadOnlyStream : IDisposable
{
// TODO : Необходимо доработать данный интерфейс для обеспечения гарантированного закрытия файла, по окончанию работы с таковым!
char ReadNextChar();

void ResetPositionToStart();
Expand Down
81 changes: 61 additions & 20 deletions TestTask/Program.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;

namespace TestTask
{
public class Program
{
const string alphabet = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
const string vowels = "аеёиоуыэюя";
const string consonants = "бвгджзйклмнпрстфхцчшщъь";

/// <summary>
/// Программа принимает на входе 2 пути до файлов.
/// Анализирует в первом файле кол-во вхождений каждой буквы (регистрозависимо). Например А, б, Б, Г и т.д.
/// Анализирует во втором файле кол-во вхождений парных букв (не регистрозависимо). Например АА, Оо, еЕ, тт и т.д.
/// Анализирует в первом файле кол-во вхождений каждой СОГЛАСНОЙ буквы (регистрозависимо). Например А, б, Б, Г и т.д.
/// Анализирует во втором файле кол-во вхождений парных ГЛАСНЫХ букв (не регистрозависимо). Например АА, Оо, еЕ, и т.д.
/// По окончанию работы - выводит данную статистику на экран.
/// </summary>
/// <param name="args">Первый параметр - путь до первого файла.
/// <param name="args">Первый параметр - путь до первого файла.
/// Второй параметр - путь до второго файла.</param>
static void Main(string[] args)
{
IReadOnlyStream inputStream1 = GetInputStream(args[0]);
IReadOnlyStream inputStream2 = GetInputStream(args[1]);
IList<LetterStats> singleLetterStats, doubleLetterStats;

IList<LetterStats> singleLetterStats = FillSingleLetterStats(inputStream1);
IList<LetterStats> doubleLetterStats = FillDoubleLetterStats(inputStream2);
using (IReadOnlyStream inputStream1 = GetInputStream(args[0]))
{ singleLetterStats = FillSingleLetterStats(inputStream1); }
using (IReadOnlyStream inputStream2 = GetInputStream(args[1]))
{ doubleLetterStats = FillDoubleLetterStats(inputStream2); }

RemoveCharStatsByType(singleLetterStats, CharType.Vowel);
RemoveCharStatsByType(doubleLetterStats, CharType.Consonants);

PrintStatistic(singleLetterStats);
PrintStatistic(doubleLetterStats);

Console.Read();
// TODO : Необжодимо дождаться нажатия клавиши, прежде чем завершать выполнение программы.
}

Expand All @@ -49,16 +56,25 @@ private static IReadOnlyStream GetInputStream(string fileFullPath)
/// <returns>Коллекция статистик по каждой букве, что была прочитана из стрима.</returns>
private static IList<LetterStats> FillSingleLetterStats(IReadOnlyStream stream)
{
List<LetterStats> fullStat = new List<LetterStats>();
foreach (char c in alphabet)
{
fullStat.Add(new LetterStats { Letter = c.ToString().ToUpper(), Count = 0 });
fullStat.Add(new LetterStats { Letter = c.ToString(), Count = 0 });
}
var fullStat_array = fullStat.ToArray();


stream.ResetPositionToStart();
while (!stream.IsEof)
{
char c = stream.ReadNextChar();
// TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - регистрозависимый.
int index = Array.FindIndex(fullStat_array, x => x.Letter == c.ToString());
if (index != -1) IncStatistic(ref fullStat_array[index]);
}

//return ???;

throw new NotImplementedException();
var result = from ls in fullStat_array where ls.Count > 0 select ls;
return result.ToList();
}

/// <summary>
Expand All @@ -70,16 +86,35 @@ private static IList<LetterStats> FillSingleLetterStats(IReadOnlyStream stream)
/// <returns>Коллекция статистик по каждой букве, что была прочитана из стрима.</returns>
private static IList<LetterStats> FillDoubleLetterStats(IReadOnlyStream stream)
{
List<LetterStats> fullStat = new List<LetterStats>();
foreach (char c in alphabet)
{
fullStat.Add(new LetterStats { Letter = c.ToString().ToUpper(), Count = 0 });
}
var fullStat_array = fullStat.ToArray();


string previousLetter = "";
stream.ResetPositionToStart();
while (!stream.IsEof)
{
char c = stream.ReadNextChar();
// TODO : заполнять статистику с использованием метода IncStatistic. Учёт букв - НЕ регистрозависимый.
string readedLetter = c.ToString().ToUpper();
if (previousLetter == readedLetter)
{
int index = Array.FindIndex(fullStat_array, x => x.Letter == readedLetter);
if (index != -1)
{
IncStatistic(ref fullStat_array[index]);//.Count++;
//чтобы не засчитать три одинаковых буквы за две пары
previousLetter = "";
continue;
}
}
previousLetter = readedLetter;
}

//return ???;

throw new NotImplementedException();
var result = from ls in fullStat_array where ls.Count > 0 select ls;
return result.ToList();
}

/// <summary>
Expand All @@ -91,15 +126,22 @@ private static IList<LetterStats> FillDoubleLetterStats(IReadOnlyStream stream)
/// <param name="charType">Тип букв для анализа</param>
private static void RemoveCharStatsByType(IList<LetterStats> letters, CharType charType)
{
string excludedLetters = "";
// TODO : Удалить статистику по запрошенному типу букв.
switch (charType)
{
case CharType.Consonants:
excludedLetters = consonants;
break;
case CharType.Vowel:
excludedLetters = vowels;
break;
}


var modifiedLetters = letters.Where(l => !excludedLetters.Contains(l.Letter) &&
!excludedLetters.Contains(l.Letter.ToLower())).ToList();
letters.Clear();
foreach (var l in modifiedLetters) letters.Add(l);
}

/// <summary>
Expand All @@ -111,15 +153,14 @@ private static void RemoveCharStatsByType(IList<LetterStats> letters, CharType c
/// <param name="letters">Коллекция со статистикой</param>
private static void PrintStatistic(IEnumerable<LetterStats> letters)
{
// TODO : Выводить на экран статистику. Выводить предварительно отсортировав по алфавиту!
throw new NotImplementedException();
foreach (var l in letters) Console.WriteLine($"{l.Letter} : {l.Count}");
}

/// <summary>
/// Метод увеличивает счётчик вхождений по переданной структуре.
/// </summary>
/// <param name="letterStats"></param>
private static void IncStatistic(LetterStats letterStats)
private static void IncStatistic(ref LetterStats letterStats)
{
letterStats.Count++;
}
Expand Down
35 changes: 27 additions & 8 deletions TestTask/ReadOnlyStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace TestTask
public class ReadOnlyStream : IReadOnlyStream
{
private Stream _localStream;
private StreamReader _localStreamReader;
private bool _disposed = false;

/// <summary>
/// Конструктор класса.
Expand All @@ -15,18 +17,17 @@ public class ReadOnlyStream : IReadOnlyStream
/// <param name="fileFullPath">Полный путь до файла для чтения</param>
public ReadOnlyStream(string fileFullPath)
{
IsEof = true;

// TODO : Заменить на создание реального стрима для чтения файла!
_localStream = null;
IsEof = false;
_localStream = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read);
_localStreamReader = new StreamReader(_localStream);
}

/// <summary>
/// Флаг окончания файла.
/// </summary>
public bool IsEof
{
get; // TODO : Заполнять данный флаг при достижении конца файла/стрима при чтении
get;
private set;
}

Expand All @@ -38,8 +39,11 @@ public bool IsEof
/// <returns>Считанный символ.</returns>
public char ReadNextChar()
{
// TODO : Необходимо считать очередной символ из _localStream
throw new NotImplementedException();
if (_disposed) throw new ObjectDisposedException("Stream is disposed");
if (IsEof) throw new EndOfStreamException();
char result = (char)_localStreamReader.Read();
IsEof = (_localStreamReader.Peek() == -1);
return result;
}

/// <summary>
Expand All @@ -56,5 +60,20 @@ public void ResetPositionToStart()
_localStream.Position = 0;
IsEof = false;
}


public void Dispose()
{
if (_disposed) return;
_disposed = true;
_localStream?.Dispose();
_localStream = null;
}






}
}
6 changes: 5 additions & 1 deletion TestTask/TestTask.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
<OutputType>Exe</OutputType>
<RootNamespace>TestTask</RootNamespace>
<AssemblyName>TestTask</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand Down Expand Up @@ -49,5 +50,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReadOnlyStream.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
3 changes: 3 additions & 0 deletions TestTask/app.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>