From e1caa3bfaa85ada441ecbe37f0b6c3f57a822b4b Mon Sep 17 00:00:00 2001 From: kamendov-maxim Date: Sun, 5 May 2024 19:56:08 +0300 Subject: [PATCH] refactoring and tests --- Bor/{ => Bor.Src}/Bor.cs | 78 +++++++++++---------- Bor/{ => Bor.Src}/Bor.csproj | 0 Bor/{ => Bor.Src}/DataStructureInterface.cs | 2 +- Bor/{ => Bor.Src}/Program.cs | 14 ++-- Bor/Bor.Tests/Bor.Tests.cs | 56 +++++++++++++++ Bor/Bor.Tests/Bor.Tests.csproj | 28 ++++++++ Bor/Bor.sln | 53 +++++++------- 7 files changed, 161 insertions(+), 70 deletions(-) rename Bor/{ => Bor.Src}/Bor.cs (61%) rename Bor/{ => Bor.Src}/Bor.csproj (100%) rename Bor/{ => Bor.Src}/DataStructureInterface.cs (82%) rename Bor/{ => Bor.Src}/Program.cs (89%) create mode 100644 Bor/Bor.Tests/Bor.Tests.cs create mode 100644 Bor/Bor.Tests/Bor.Tests.csproj diff --git a/Bor/Bor.cs b/Bor/Bor.Src/Bor.cs similarity index 61% rename from Bor/Bor.cs rename to Bor/Bor.Src/Bor.cs index 4e710b2..2ad8a54 100644 --- a/Bor/Bor.cs +++ b/Bor/Bor.Src/Bor.cs @@ -7,7 +7,7 @@ using System.Runtime.CompilerServices; using System.Xml; -namespace Data_Structure; +namespace Data_Structures; public class Bor : IDataStructure { public Bor() @@ -35,15 +35,19 @@ public bool Add(string element) bool answer = false; for (int i = 0; i < element.Length; i++) { - // Node newTrie; - if (tempRoot.Children.Keys.Contains(element[i])) + if (tempRoot.Children.TryGetValue(element[i], out Node? value)) { - tempRoot = tempRoot.Children[element[i]]; + tempRoot = value; + if (!tempRoot.endOfWord && i == element.Length - 1) + { + tempRoot.endOfWord = true; + return true; + } } else { answer = true; - Node newTrie = new Node(); + var newTrie = new Node(); if (total == i) { @@ -63,9 +67,9 @@ public bool Contains(string element) int total = element.Length - 1; for (int i = 0; i < element.Length; i++) { - if (tempRoot.Children.Keys.Contains(element[i])) + if (tempRoot.Children.TryGetValue(element[i], out Node? value)) { - tempRoot = tempRoot.Children[element[i]]; + tempRoot = value; if (total == i) { @@ -85,40 +89,41 @@ public bool Contains(string element) public bool Remove(string element) { - (bool wordWasHere, bool f) = RemoveRecursion(this.root, element, 0); - return wordWasHere; - } - - private Tuple RemoveRecursion(Node root, string element, int charNumber) - { - bool wordWasHere = false; - bool finish = false; - if (charNumber == element.Length) + Node? nodeFromWhereToDelete = null; + char startOfWordToDelete = default; + var previousNode = root; + int i = 0; + for (i = 0; i < element.Length; ++i) { - return Tuple.Create(true, root.Children.Count > 0); - } - if (root.Children.ContainsKey(element[charNumber])) - { - (wordWasHere, finish) = RemoveRecursion(root.Children[element[charNumber]], element, charNumber + 1); - if (wordWasHere && charNumber == element.Length - 1) + 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 { - root.endOfWord = false; + return false; } } - else - { - return Tuple.Create(false, true); - } - if (wordWasHere && !finish) - { - root.Children.Remove(element[charNumber]); - } - if (!finish) + if (nodeFromWhereToDelete is null) { - finish = root.Children.Count > 0; + throw new InvalidOperationException("Trie does not work correclty"); } - return Tuple.Create(wordWasHere, finish); + + nodeFromWhereToDelete.Children.Remove(startOfWordToDelete); + + return true; } public int HowManyStartsWithPrefix(string prefix) @@ -139,7 +144,7 @@ public int HowManyStartsWithPrefix(string prefix) return PrefixRecursion(tempNode); } - private int PrefixRecursion(Node root) + private static int PrefixRecursion(Node root) { int answer = 0; var nodes = root.Children.Select(x => x.Value); @@ -155,6 +160,5 @@ private int PrefixRecursion(Node root) } public int Size; - private Node root; - private int globalWordCount; + private readonly Node root; } diff --git a/Bor/Bor.csproj b/Bor/Bor.Src/Bor.csproj similarity index 100% rename from Bor/Bor.csproj rename to Bor/Bor.Src/Bor.csproj diff --git a/Bor/DataStructureInterface.cs b/Bor/Bor.Src/DataStructureInterface.cs similarity index 82% rename from Bor/DataStructureInterface.cs rename to Bor/Bor.Src/DataStructureInterface.cs index 9b83e8c..94105f3 100644 --- a/Bor/DataStructureInterface.cs +++ b/Bor/Bor.Src/DataStructureInterface.cs @@ -1,4 +1,4 @@ -namespace Data_Structure; +namespace Data_Structures; interface IDataStructure { diff --git a/Bor/Program.cs b/Bor/Bor.Src/Program.cs similarity index 89% rename from Bor/Program.cs rename to Bor/Bor.Src/Program.cs index 69f9a6e..423ec58 100644 --- a/Bor/Program.cs +++ b/Bor/Bor.Src/Program.cs @@ -1,5 +1,5 @@ using System.Runtime.InteropServices; -using Data_Structure; +using Data_Structures; class Program { @@ -37,8 +37,8 @@ public static UserInput GetUserInput() public static void Main() { - Bor myBor = new Bor(); - UserInput input = UserInput.checkWord; + var myBor = new Bor(); + var input = UserInput.checkWord; while (input != UserInput.exitProgram) { PrintOptions(); @@ -49,7 +49,7 @@ public static void Main() { Console.WriteLine("Введите строку"); string? str = Console.ReadLine(); - myBor.Add(str); + myBor.Add(str!); Console.WriteLine("Строка добавлена"); break; } @@ -58,7 +58,7 @@ public static void Main() { Console.WriteLine("Введите строку"); string? str = Console.ReadLine(); - if (myBor.Contains(str)) + if (myBor.Contains(str!)) { Console.WriteLine("Такая строка есть"); } @@ -78,7 +78,7 @@ public static void Main() Console.WriteLine("Введите строку"); string? str = Console.ReadLine(); - myBor.Remove(str); + myBor.Remove(str!); Console.WriteLine("Строка удалена"); break; } @@ -86,7 +86,7 @@ public static void Main() { Console.WriteLine("Введите префикс"); string? str = Console.ReadLine(); - Console.WriteLine($"Слов с таким префиксом: {myBor.HowManyStartsWithPrefix(str)}"); + Console.WriteLine($"Слов с таким префиксом: {myBor.HowManyStartsWithPrefix(str!)}"); break; } case UserInput.exitProgram: diff --git a/Bor/Bor.Tests/Bor.Tests.cs b/Bor/Bor.Tests/Bor.Tests.cs new file mode 100644 index 0000000..9845596 --- /dev/null +++ b/Bor/Bor.Tests/Bor.Tests.cs @@ -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)); + } + } + } +} \ No newline at end of file diff --git a/Bor/Bor.Tests/Bor.Tests.csproj b/Bor/Bor.Tests/Bor.Tests.csproj new file mode 100644 index 0000000..8a7d5e0 --- /dev/null +++ b/Bor/Bor.Tests/Bor.Tests.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + diff --git a/Bor/Bor.sln b/Bor/Bor.sln index 7b0ab5f..09557dc 100644 --- a/Bor/Bor.sln +++ b/Bor/Bor.sln @@ -1,25 +1,28 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.002.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bor", "Bor.csproj", "{3E4A2A9D-6E00-4949-8262-52D4A299CD41}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3E4A2A9D-6E00-4949-8262-52D4A299CD41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3E4A2A9D-6E00-4949-8262-52D4A299CD41}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3E4A2A9D-6E00-4949-8262-52D4A299CD41}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3E4A2A9D-6E00-4949-8262-52D4A299CD41}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {24B336AF-AE4F-4566-96F6-B52F396BE150} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bor", "Bor.Src\Bor.csproj", "{349241AF-51B9-48AC-8F13-32D18AD15491}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bor.Tests", "Bor.Tests\Bor.Tests.csproj", "{9A666E6C-CA14-440A-BBFA-2A6066DEAC7F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {349241AF-51B9-48AC-8F13-32D18AD15491}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {349241AF-51B9-48AC-8F13-32D18AD15491}.Debug|Any CPU.Build.0 = Debug|Any CPU + {349241AF-51B9-48AC-8F13-32D18AD15491}.Release|Any CPU.ActiveCfg = Release|Any CPU + {349241AF-51B9-48AC-8F13-32D18AD15491}.Release|Any CPU.Build.0 = Release|Any CPU + {9A666E6C-CA14-440A-BBFA-2A6066DEAC7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A666E6C-CA14-440A-BBFA-2A6066DEAC7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A666E6C-CA14-440A-BBFA-2A6066DEAC7F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A666E6C-CA14-440A-BBFA-2A6066DEAC7F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal