Skip to content

Commit

Permalink
Merge pull request #2 from kamendov-maxim/Bor
Browse files Browse the repository at this point in the history
Бор
  • Loading branch information
kamendov-maxim authored Oct 10, 2024
2 parents 2ef6d2d + e1caa3b commit 6aa0025
Show file tree
Hide file tree
Showing 7 changed files with 396 additions and 0 deletions.
164 changes: 164 additions & 0 deletions Bor/Bor.Src/Bor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
using System.Buffers.Binary;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq.Expressions;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Xml;

namespace Data_Structures;
public class Bor : IDataStructure
{
public Bor()
{
this.Size = 0;
this.root = new Node();
}

private class Node
{
public Node()
{
this.Children = new Dictionary<char, Node>();
endOfWord = false;
}

public Dictionary<char, Node> Children;
public bool endOfWord;
}

public bool Add(string element)
{
Node tempRoot = root;
int total = element.Length - 1;
bool answer = false;
for (int i = 0; i < element.Length; i++)
{
if (tempRoot.Children.TryGetValue(element[i], out Node? value))
{
tempRoot = value;
if (!tempRoot.endOfWord && i == element.Length - 1)
{
tempRoot.endOfWord = true;
return true;
}
}
else
{
answer = true;
var newTrie = new Node();

if (total == i)
{
newTrie.endOfWord = true;
}

tempRoot.Children.Add(element[i], newTrie);
tempRoot = newTrie;
}
}
return answer;
}

public bool Contains(string element)
{
Node tempRoot = root;
int total = element.Length - 1;
for (int i = 0; i < element.Length; i++)
{
if (tempRoot.Children.TryGetValue(element[i], out Node? value))
{
tempRoot = value;

if (total == i)
{
if (tempRoot.endOfWord == true)
{
return true;
}
}
}
else
{
return false;
}
}
return false;
}

public bool Remove(string element)
{
Node? nodeFromWhereToDelete = null;
char startOfWordToDelete = default;
var previousNode = root;
int i = 0;
for (i = 0; i < element.Length; ++i)
{
if (previousNode.Children.TryGetValue(element[i], out Node? currentNode))
{
if (i + 1 == element.Length && currentNode.endOfWord == true && currentNode.Children.Count > 0)
{
currentNode.endOfWord = false;
return true;
}
if (nodeFromWhereToDelete is null || currentNode.Children.Count > 1)
{
nodeFromWhereToDelete = currentNode;
startOfWordToDelete = element[i + 1];
}

previousNode = currentNode;
}
else
{
return false;
}
}

if (nodeFromWhereToDelete is null)
{
throw new InvalidOperationException("Trie does not work correclty");
}

nodeFromWhereToDelete.Children.Remove(startOfWordToDelete);

return true;
}

public int HowManyStartsWithPrefix(string prefix)
{
Node tempNode = root;
int total = prefix.Length - 1;
for (int i = 0; i < prefix.Length; i++)
{
if (tempNode.Children.ContainsKey(prefix[i]))
{
tempNode = tempNode.Children[prefix[i]];
}
else
{
return 0;
}
}
return PrefixRecursion(tempNode);
}

private static int PrefixRecursion(Node root)
{
int answer = 0;
var nodes = root.Children.Select(x => x.Value);
foreach (var node in nodes)
{
if (node.endOfWord)
{
++answer;
}
answer += PrefixRecursion(node);
}
return answer;
}

public int Size;
private readonly Node root;
}
10 changes: 10 additions & 0 deletions Bor/Bor.Src/Bor.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
10 changes: 10 additions & 0 deletions Bor/Bor.Src/DataStructureInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Data_Structures;

interface IDataStructure
{
bool Add(string element);

bool Contains(string element);

bool Remove(string element);
}
100 changes: 100 additions & 0 deletions Bor/Bor.Src/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System.Runtime.InteropServices;
using Data_Structures;

class Program
{
public enum UserInput
{
addEntry,
checkWord,
removeEntry,
wordsWithPrefix,
printSize,
exitProgram
}

public static void PrintOptions()
{
Console.WriteLine("Введите команду:");
Console.WriteLine("0 - добавить слово");
Console.WriteLine("1 - проверить, есть ли такое слово");
Console.WriteLine("2 - удалить слово");
Console.WriteLine("3 - посчитать количество слов с префиксом");
Console.WriteLine("4 - посчитать размер бора");
Console.WriteLine("5 - выйти");
}

public static UserInput GetUserInput()
{
int userInput = Convert.ToInt32(Console.ReadLine());
while (!typeof(UserInput).IsEnumDefined(userInput))
{
Console.WriteLine("Введите цифру от 0 до 5");
userInput = Convert.ToInt32(Console.ReadLine());
}
return (UserInput)userInput;
}

public static void Main()
{
var myBor = new Bor();
var input = UserInput.checkWord;
while (input != UserInput.exitProgram)
{
PrintOptions();
input = GetUserInput();
switch (input)
{
case UserInput.addEntry:
{
Console.WriteLine("Введите строку");
string? str = Console.ReadLine();
myBor.Add(str!);
Console.WriteLine("Строка добавлена");
break;
}
case
UserInput.checkWord:
{
Console.WriteLine("Введите строку");
string? str = Console.ReadLine();
if (myBor.Contains(str!))
{
Console.WriteLine("Такая строка есть");
}
else
{
Console.WriteLine("Такой строки нет");
}
break;
}
case UserInput.printSize:
{
Console.WriteLine($"Размер бора - {myBor.Size}");
break;
}
case UserInput.removeEntry:
{

Console.WriteLine("Введите строку");
string? str = Console.ReadLine();
myBor.Remove(str!);
Console.WriteLine("Строка удалена");
break;
}
case UserInput.wordsWithPrefix:
{
Console.WriteLine("Введите префикс");
string? str = Console.ReadLine();
Console.WriteLine($"Слов с таким префиксом: {myBor.HowManyStartsWithPrefix(str!)}");
break;
}
case UserInput.exitProgram:
{
Console.WriteLine("Заврешение работы программы");
break;
}
}
}
}
}
56 changes: 56 additions & 0 deletions Bor/Bor.Tests/Bor.Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace Bor.Tests;
using Data_Structures;

public class Tests
{
Bor trie;
readonly string[] testStrings = ["abcdef", "abcdrfg", "abuq", "abcdeyunkhnrlnh",
"slgbfb;gajga", "sldgaslgnlkg", "agdfjhahg"];

[SetUp]
public void Setup()
{
trie = new();
}

[Test]
public void Test1()
{
foreach (string testString in testStrings)
trie.Add(testString);

foreach (var testString in testStrings)
{
Assert.That(trie.Contains(testString));
}

trie.Remove("abcdef");

foreach (var testString in testStrings)
{
if (testString == "abcdef")
{
Assert.That(!trie.Contains(testString));
}
else
{
Assert.That(trie.Contains(testString));
}
}

trie.Remove("abcdeyunkhnrlnh");
trie.Remove("slgbfb;gajga");

foreach (var testString in testStrings)
{
if (testString == "abcdef" || testString == "abcdeyunkhnrlnh" || testString == "slgbfb;gajga")
{
Assert.That(!trie.Contains(testString));
}
else
{
Assert.That(trie.Contains(testString));
}
}
}
}
28 changes: 28 additions & 0 deletions Bor/Bor.Tests/Bor.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>

<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Bor.Src\Bor.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit 6aa0025

Please sign in to comment.