Skip to content

Commit e683641

Browse files
committed
Add trie data structure and tests
1 parent d0c57ac commit e683641

File tree

4 files changed

+101
-12
lines changed

4 files changed

+101
-12
lines changed
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
32
<PropertyGroup>
43
<TargetFramework>net6.0</TargetFramework>
54
<LangVersion>latest</LangVersion>
65
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
76
<IsPackable>false</IsPackable>
87
<GenerateProgramFile>false</GenerateProgramFile>
98
</PropertyGroup>
10-
119
<ItemGroup>
1210
<Compile Include="Math/*.fs" />
1311
<Compile Include="Search/*.fs" />
1412
<Compile Include="Sort/*.fs" />
1513
<Compile Include="Strings/*.fs" />
14+
<Compile Include="DataStructures/*.fs" />
1615
<Compile Include="Program.fs" />
1716
</ItemGroup>
18-
1917
<ItemGroup>
2018
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
2119
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
@@ -25,9 +23,7 @@
2523
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2624
</PackageReference>
2725
</ItemGroup>
28-
2926
<ItemGroup>
3027
<ProjectReference Include="..\Algorithms\Algorithms.fsproj" />
3128
</ItemGroup>
32-
33-
</Project>
29+
</Project>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
namespace Algorithms.Tests.DataStructures
2+
3+
open Microsoft.VisualStudio.TestTools.UnitTesting
4+
open Algorithms.DataStructures.Trie
5+
6+
[<TestClass>]
7+
type TrieTests () =
8+
9+
[<TestMethod>]
10+
member this.``Test insertion and retrieval with strings``() =
11+
let mutable trie = empty
12+
13+
trie <- insert "foo" trie
14+
Assert.IsTrue(search "foo" trie)
15+
16+
trie <- insert "foobar" trie
17+
Assert.IsTrue(search "foobar" trie)
18+
Assert.IsTrue(search "foo" trie)
19+
20+
trie <- insert "bar" trie
21+
Assert.IsTrue(search "bar" trie)
22+
Assert.IsFalse(search "baz" trie)
23+
Assert.IsFalse(search "foobarbaz" trie)
24+
25+
[<TestMethod>]
26+
member this.``Test empty trie``() =
27+
let trie = empty
28+
Assert.IsFalse(search "foo" trie)
29+
Assert.IsFalse(search "" trie)
30+
31+
[<TestMethod>]
32+
member this.``Test insert empty key``() =
33+
let mutable trie = empty
34+
35+
trie <- insert "" trie
36+
Assert.IsTrue(search "" trie)
37+
Assert.IsFalse(search "foo" trie)
38+
39+
[<TestMethod>]
40+
member this.``Test overlapping keys``() =
41+
let mutable trie = empty
42+
43+
trie <- insert "car" trie
44+
trie <- insert "cart" trie
45+
trie <- insert "carter" trie
46+
47+
Assert.IsTrue(search "car" trie)
48+
Assert.IsTrue(search "cart" trie)
49+
Assert.IsTrue(search "carter" trie)
50+
Assert.IsFalse(search "care" trie)
51+
52+
[<TestMethod>]
53+
member this.``Test partial match``() =
54+
let mutable trie = empty
55+
56+
trie <- insert "apple" trie
57+
Assert.IsFalse(search "app" trie)
58+
Assert.IsFalse(search "appl" trie)
59+
Assert.IsTrue(search "apple" trie)
60+
Assert.IsFalse(search "applepie" trie)

Algorithms/Algorithms.fsproj

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1-
<?xml version="1.0" encoding="utf-8"?>
21
<Project Sdk="Microsoft.NET.Sdk">
3-
42
<PropertyGroup>
53
<OutputType>Library</OutputType>
64
<TargetFramework>net6.0</TargetFramework>
75
<LangVersion>latest</LangVersion>
86
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
97
</PropertyGroup>
10-
118
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
129
<DefineConstants>TRACE</DefineConstants>
1310
</PropertyGroup>
14-
1511
<ItemGroup>
1612
<Compile Include="Math/*.fs" />
1713
<Compile Include="Search/*.fs" />
1814
<Compile Include="Sort/*.fs" />
1915
<Compile Include="Strings/*.fs" />
16+
<Compile Include="DataStructures/*.fs" />
2017
</ItemGroup>
21-
22-
</Project>
18+
</Project>

Algorithms/DataStructures/Trie.fs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace Algorithms.DataStructures
2+
3+
module Trie =
4+
5+
type Trie = {
6+
IsWord : bool
7+
Children : Map<char, Trie>
8+
}
9+
10+
let empty : Trie = { IsWord = false; Children = Map.empty }
11+
12+
let insert (word: string) (trie: Trie) : Trie =
13+
let rec insertImpl (chars: char list) (trie: Trie) : Trie =
14+
match chars with
15+
| [] ->
16+
{ trie with IsWord = true }
17+
| c :: rest ->
18+
match trie.Children.TryFind c with
19+
| Some child ->
20+
let child = insertImpl rest child
21+
{ trie with Children = trie.Children.Add(c, child) }
22+
| None ->
23+
let child = insertImpl rest empty
24+
{ trie with Children = trie.Children.Add(c, child) }
25+
26+
insertImpl (word |> Seq.toList) trie
27+
28+
let search (word: string) (trie: Trie) : bool =
29+
let rec searchImpl (chars: char list) (trie: Trie) : bool =
30+
match chars with
31+
| [] -> trie.IsWord
32+
| c :: rest ->
33+
match trie.Children.TryFind c with
34+
| Some child -> searchImpl rest child
35+
| None -> false
36+
searchImpl (word |> Seq.toList) trie
37+

0 commit comments

Comments
 (0)