Skip to content

Commit 66a8b29

Browse files
committed
Implement R-ways search tries
1 parent f353c67 commit 66a8b29

File tree

5 files changed

+235
-1
lines changed

5 files changed

+235
-1
lines changed

Algorithms/Algorithms.csproj

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<TargetFramework>netstandard1.4</TargetFramework>
44
</PropertyGroup>
55
<ItemGroup>
6-
<Folder Include="DataStructures\SearchTries" />
76
<Folder Include="Selection" />
87
</ItemGroup>
98
<ItemGroup>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
5+
namespace Algorithms.DataStructures.SearchTries
6+
{
7+
public interface ISearchTries<T>
8+
{
9+
T this[string key] { get; set; }
10+
11+
int Count { get; }
12+
bool IsEmpty { get; }
13+
14+
void Delete(String key);
15+
bool ContainsKey(String key);
16+
17+
IEnumerable<string> Keys { get; }
18+
IEnumerable<string> KeysWithPrefix(string prefix);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+

2+
3+
using System;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
using Algorithms.DataStructures.Queue;
7+
using Algorithms.Utils;
8+
9+
namespace Algorithms.DataStructures.SearchTries
10+
{
11+
public class RWayTries<T> : ISearchTries<T>
12+
{
13+
private const int R = 256;
14+
private int N = 0;
15+
16+
private class Node
17+
{
18+
internal T value;
19+
internal Node[] children = new Node[R];
20+
}
21+
22+
private Node root;
23+
24+
public T this[string key]
25+
{
26+
get
27+
{
28+
var x = Get(root, key, 0);
29+
if (x != null)
30+
{
31+
return x.value;
32+
}
33+
return default(T);
34+
}
35+
set
36+
{
37+
root = Put(root, key, value, 0);
38+
39+
}
40+
}
41+
42+
private Node Put(Node x, string key, T value, int d)
43+
{
44+
if (x == null)
45+
{
46+
x = new Node();
47+
}
48+
49+
if (key.Length == d)
50+
{
51+
if (ObjectUtil.IsNullOrDefault(x.value))
52+
{
53+
N++;
54+
}
55+
56+
x.value = value;
57+
return x;
58+
}
59+
60+
char v = key[d];
61+
x.children[v] = Put(x.children[v], key, value, d + 1);
62+
return x;
63+
}
64+
65+
public void Delete(String key)
66+
{
67+
Node x = Get(root, key, 0);
68+
if (x != null)
69+
{
70+
N--;
71+
x.value = default(T);
72+
}
73+
}
74+
75+
public bool ContainsKey(String key)
76+
{
77+
Node x = Get(root, key, 0);
78+
if (x == null) return false;
79+
return !ObjectUtil.IsNullOrDefault(x.value);
80+
}
81+
82+
public IEnumerable<string> Keys {
83+
get
84+
{
85+
var queue = new QueueLinkedList<string>();
86+
87+
Collect(root, "", queue);
88+
89+
return queue;
90+
}
91+
}
92+
93+
public IEnumerable<string> KeysWithPrefix(string prefix)
94+
{
95+
96+
Node x = Get(root, prefix, 0);
97+
QueueLinkedList<String> queue = new QueueLinkedList<string>();
98+
if (x != null)
99+
{
100+
Collect(x, prefix, queue);
101+
}
102+
return queue;
103+
}
104+
105+
private void Collect(Node x, String prefix, IQueue<string> queue)
106+
{
107+
if (x == null) return;
108+
if (!ObjectUtil.IsNullOrDefault(x.value))
109+
{
110+
queue.Enqueue(prefix);
111+
}
112+
for (int r = 0; r < R; ++r)
113+
{
114+
Collect(x.children[r], prefix + ((char)r), queue);
115+
}
116+
}
117+
118+
private Node Get(Node x, string key, int d)
119+
{
120+
if (x == null) return null;
121+
if (key.Length == d) return x;
122+
char v = key[d];
123+
return Get(x.children[v], key, d + 1);
124+
}
125+
126+
public int Count => N;
127+
public bool IsEmpty => N == 0;
128+
129+
130+
}
131+
}

Algorithms/Utils/ObjectUtil.cs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
3+
namespace Algorithms.Utils
4+
{
5+
public class ObjectUtil
6+
{
7+
public static bool IsNullOrDefault<T>(T argument)
8+
{
9+
// deal with normal scenarios
10+
if (argument == null) return true;
11+
if (object.Equals(argument, default(T))) return true;
12+
13+
// deal with non-null nullables
14+
Type methodType = typeof(T);
15+
if (Nullable.GetUnderlyingType(methodType) != null) return false;
16+
17+
// deal with boxed value types
18+
Type argumentType = argument.GetType();
19+
if (argumentType != methodType)
20+
{
21+
object obj = Activator.CreateInstance(argument.GetType());
22+
return obj.Equals(argument);
23+
}
24+
25+
return false;
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System.Reflection.PortableExecutable;
2+
using Algorithms.DataStructures.HashMap;
3+
using Algorithms.DataStructures.SearchTries;
4+
using Algorithms.DataStructures.TreeMap;
5+
using Xunit;
6+
using Xunit.Abstractions;
7+
8+
namespace AlgorithmsUnitTest.DataStrutures.TreeMap
9+
{
10+
public class RWayTriesUnitTest
11+
{
12+
private ITestOutputHelper console;
13+
public RWayTriesUnitTest(ITestOutputHelper console)
14+
{
15+
this.console = console;
16+
}
17+
18+
[Fact]
19+
public void TestHashMap()
20+
{
21+
var map = new RWayTries<int>();
22+
Assert.True(map.IsEmpty);
23+
map["one"] = 1;
24+
Assert.Equal(1, map["one"]);
25+
map["two"] = 2;
26+
Assert.Equal(2, map["two"]);
27+
Assert.Equal(2, map.Count);
28+
29+
30+
map.Delete("two");
31+
Assert.Equal(1, map.Count);
32+
Assert.True(map.ContainsKey("one"));
33+
Assert.False(map.ContainsKey("two"));
34+
Assert.False(map.IsEmpty);
35+
36+
37+
foreach(var key in map.Keys)
38+
{
39+
console.WriteLine("{0}", key);
40+
}
41+
42+
map["test"] = 3;
43+
map["te"] = 4;
44+
map["team"] = 4;
45+
map["dream"] = 2;
46+
47+
int count = 0;
48+
foreach (var key in map.KeysWithPrefix("te"))
49+
{
50+
count++;
51+
console.WriteLine("{0}", key);
52+
}
53+
Assert.Equal(3, count);
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)