-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trie #3
base: main
Are you sure you want to change the base?
Trie #3
Changes from all commits
7e8ff5c
98aa5d5
cfc5462
3d4466c
9fa99cf
9fad293
9cfef27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
namespace TrieClass | ||
{ | ||
/// <summary> | ||
/// Trie class. | ||
/// </summary> | ||
public class Trie | ||
{ | ||
private readonly Dictionary<char, Trie> children; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Trie"/> class. | ||
/// </summary> | ||
public Trie() | ||
{ | ||
this.children = []; | ||
this.IsTerminal = false; | ||
this.CountOfTerminalsFarther = 0; | ||
} | ||
|
||
/// <summary> | ||
/// Gets a value indicating whether the edge is terminal. | ||
/// </summary> | ||
public bool IsTerminal { get; private set; } | ||
|
||
/// <summary> | ||
/// Gets the trie size. | ||
/// </summary> | ||
public int Size => this.CountOfTerminalsFarther; | ||
|
||
private int CountOfTerminalsFarther { get; set; } | ||
|
||
/// <summary> | ||
/// Adds given string to trie. | ||
/// </summary> | ||
/// <param name="element">String to add to the trie.</param> | ||
/// <returns>True if successful, otherwise false.</returns> | ||
public bool Add(string element) | ||
{ | ||
if (element.Length == 0) | ||
{ | ||
if (this.IsTerminal) | ||
{ | ||
return false; | ||
} | ||
|
||
this.IsTerminal = true; | ||
this.CountOfTerminalsFarther++; | ||
|
||
return true; | ||
} | ||
|
||
if (!this.children.TryGetValue(element[0], out Trie? child)) | ||
{ | ||
child = new Trie(); | ||
this.children.Add(element[0], child); | ||
} | ||
|
||
if (child.Add(element[1..])) | ||
{ | ||
this.CountOfTerminalsFarther++; | ||
|
||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// Checks whether the element is contained in the trie. | ||
/// </summary> | ||
/// <param name="element">The element that needs to be checked if it is in the trie.</param> | ||
/// <returns>True if successful, otherwise false.</returns> | ||
public bool Contains(string element) | ||
{ | ||
Trie? result = this.FindEdgeWithKey(element); | ||
|
||
return result != null && result.IsTerminal; | ||
} | ||
|
||
/// <summary> | ||
/// Removes an element from the trie. | ||
/// </summary> | ||
/// <param name="element">The element to be removed from the trie.</param> | ||
/// <returns>True if successful, otherwise false.</returns> | ||
public bool Remove(string element) | ||
{ | ||
if (element.Length == 0) | ||
{ | ||
if (!this.IsTerminal) | ||
{ | ||
return false; | ||
} | ||
|
||
this.CountOfTerminalsFarther--; | ||
this.IsTerminal = false; | ||
|
||
return true; | ||
} | ||
|
||
if (!this.children.TryGetValue(element[0], out Trie? value)) | ||
{ | ||
return false; | ||
} | ||
|
||
if (value.Remove(element[1..])) | ||
{ | ||
this.CountOfTerminalsFarther--; | ||
if (value.CountOfTerminalsFarther == 0) | ||
{ | ||
this.children.Remove(element[0]); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// Searches for how many trie elements start with a given prefix. | ||
/// </summary> | ||
/// <param name="prefix">The prefix for the search.</param> | ||
/// <returns>The number of elements starting with this prefix.</returns> | ||
public int HowManyStartsWithPrefix(string prefix) | ||
{ | ||
if (prefix.Length == 0) | ||
{ | ||
return this.CountOfTerminalsFarther; | ||
} | ||
|
||
if (!this.children.TryGetValue(prefix[0], out Trie? edge)) | ||
{ | ||
return 0; | ||
} | ||
|
||
return edge.HowManyStartsWithPrefix(prefix[1..]); | ||
} | ||
|
||
private Trie? FindEdgeWithKey(string key) | ||
{ | ||
if (key.Length == 0) | ||
{ | ||
return this; | ||
} | ||
|
||
if (!this.children.TryGetValue(key[0], out Trie? child)) | ||
{ | ||
return null; | ||
} | ||
|
||
return child.FindEdgeWithKey(key[1..]); | ||
} | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Вообще, я имел ввиду не убирать целиком анализатор, а отключать конкретные варнинги, которые себя криво ведут 🤔 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
| ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.9.34607.119 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trie", "Trie.csproj", "{B7F7A03C-3413-46A2-B23F-23680C6067B2}" | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrieTests", "..\TrieTests\TrieTests.csproj", "{1C42C607-28FA-4520-A656-ABA4702B9BBA}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{B7F7A03C-3413-46A2-B23F-23680C6067B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{B7F7A03C-3413-46A2-B23F-23680C6067B2}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{B7F7A03C-3413-46A2-B23F-23680C6067B2}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{B7F7A03C-3413-46A2-B23F-23680C6067B2}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{1C42C607-28FA-4520-A656-ABA4702B9BBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{1C42C607-28FA-4520-A656-ABA4702B9BBA}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{1C42C607-28FA-4520-A656-ABA4702B9BBA}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{1C42C607-28FA-4520-A656-ABA4702B9BBA}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {FE822E7C-39B7-4707-B1DA-DB3584687258} | ||
EndGlobalSection | ||
EndGlobal |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Стоило бы добавить хоть один тест на |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using TrieClass; | ||
|
||
[TestFixture] | ||
public class TrieTests | ||
{ | ||
private Trie trie; | ||
|
||
[SetUp] | ||
public void Setup() | ||
{ | ||
trie = new Trie(); | ||
} | ||
|
||
[Test] | ||
public void AddElement_ReturnsTrue() | ||
{ | ||
Assert.IsTrue(trie.Add("hello")); | ||
} | ||
|
||
[Test] | ||
public void AddExistingElement_ReturnsFalse() | ||
{ | ||
trie.Add("hello"); | ||
Assert.IsFalse(trie.Add("hello")); | ||
} | ||
|
||
[Test] | ||
public void ContainsElement_ReturnsTrue() | ||
{ | ||
trie.Add("world"); | ||
Assert.IsTrue(trie.Contains("world")); | ||
} | ||
|
||
[Test] | ||
public void DoesNotContainElement_ReturnsFalse() | ||
{ | ||
Assert.IsFalse(trie.Contains("world")); | ||
} | ||
|
||
[Test] | ||
public void RemoveElement_ReturnsTrue() | ||
{ | ||
trie.Add("apple"); | ||
Assert.IsTrue(trie.Remove("apple")); | ||
} | ||
|
||
[Test] | ||
public void RemoveNotExistingElement_ReturnsFalse() | ||
{ | ||
Assert.IsFalse(trie.Remove("hello")); | ||
} | ||
|
||
[Test] | ||
public void HowManyStartsWithPrefix_ReturnsCorrectCount() | ||
{ | ||
trie.Add("cat"); | ||
trie.Add("car"); | ||
trie.Add("dog"); | ||
Assert.That(trie.HowManyStartsWithPrefix("c"), Is.EqualTo(2)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>true</IsTestProject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<None Include="..\Trie\.editorconfig" Link=".editorconfig" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="coverlet.collector" Version="6.0.0" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> | ||
<PackageReference Include="Microsoft.Playwright.NUnit" Version="1.27.1" /> | ||
<PackageReference Include="NUnit" Version="3.14.0" /> | ||
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" /> | ||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Trie\Trie.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Using Include="Microsoft.Playwright.NUnit" /> | ||
<Using Include="NUnit.Framework" /> | ||
<Using Include="System.Text.RegularExpressions" /> | ||
<Using Include="System.Threading.Tasks" /> | ||
</ItemGroup> | ||
|
||
</Project> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не уверен, почему бы не объединить их в одно поле, но если уж делаем private ..., то геттеры и сеттеры писать не надо.


Без геттеров/сеттеров - это будет честное поле класса. С геттерами/сеттерами это будет поле класса, спрятанное под функциями гет и сет.