Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added a ternary search tree.

  • Loading branch information...
commit 27fa30885fc1f75f9241307ff8e455e470c26b4d 1 parent 656840a
@SuprDewd authored
View
231 SharpBag/Collections/TernarySearchTree.cs
@@ -0,0 +1,231 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+
+namespace SharpBag.Collections
+{
+ /// <summary>
+ /// A ternary search tree.
+ /// </summary>
+ /// <typeparam name="T">The type of items in the tree.</typeparam>
+ public class TernarySearchTree<T> : IEnumerable<T[]> where T : IComparable<T>
+ {
+ private class Node
+ {
+ public T Value { get; private set; }
+
+ public bool IsEnd { get; set; }
+
+ public Node Below { get; set; }
+
+ public Node Left { get; set; }
+
+ public Node Right { get; set; }
+
+ public Node(T value)
+ {
+ this.Value = value;
+ this.IsEnd = false;
+ }
+
+ public Node GetNextFor(T value)
+ {
+ return this.GetNextFor(this.Value.CompareTo(value));
+ }
+
+ public Node GetNextFor(int cmp)
+ {
+ if (cmp == 0) return this.Below;
+ if (cmp > 0) return this.Left;
+ return this.Right;
+ }
+
+ public void Add(Node node)
+ {
+ this.Add(node, this.Value.CompareTo(node.Value));
+ }
+
+ public void Add(Node node, int cmp)
+ {
+ if (cmp == 0) this.Below = node;
+ else if (cmp > 0) this.Left = node;
+ else this.Right = node;
+ }
+ }
+
+ /// <summary>
+ /// Gets the item count.
+ /// </summary>
+ public int Count { get; private set; }
+
+ /// <summary>
+ /// Gets the items.
+ /// </summary>
+ public IEnumerable<T[]> Items
+ {
+ get
+ {
+ foreach (var item in this.StartingWith(new T[0], this.Root))
+ {
+ yield return item;
+ }
+ }
+ }
+
+ private Node Root { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TernarySearchTree&lt;T&gt;"/> class.
+ /// </summary>
+ public TernarySearchTree() { Count = 0; }
+
+ /// <summary>
+ /// Adds the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence.</param>
+ /// <returns>Whether the sequence was new.</returns>
+ public virtual bool Add(T[] sequence)
+ {
+ Contract.Requires(sequence.Length > 0);
+ bool isNew = false;
+
+ if (this.Root == null)
+ {
+ this.Root = new Node(sequence[0]);
+ isNew = true;
+ }
+
+ Node cur = this.Root;
+ for (int i = 0; i < sequence.Length; i++)
+ {
+ int cmp = cur.Value.CompareTo(sequence[i]);
+
+ if (cmp == 0)
+ {
+ if (i < sequence.Length - 1)
+ {
+ if (cur.Below == null)
+ {
+ cur.Below = new Node(sequence[i + 1]);
+ isNew = true;
+ }
+
+ cur = cur.Below;
+ }
+ }
+ else if (cmp > 0)
+ {
+ if (cur.Left == null)
+ {
+ cur.Left = new Node(sequence[i]);
+ isNew = true;
+ }
+
+ cur = cur.Left;
+ i--;
+ }
+ else
+ {
+ if (cur.Right == null)
+ {
+ cur.Right = new Node(sequence[i]);
+ isNew = true;
+ }
+
+ cur = cur.Right;
+ i--;
+ }
+
+ if (i + 1 == sequence.Length)
+ {
+ if (!cur.IsEnd) isNew = true;
+ cur.IsEnd = true;
+ }
+ }
+
+ if (isNew) this.Count++;
+ return isNew;
+ }
+
+ /// <summary>
+ /// Determines whether the current instance contains the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence.</param>
+ /// <returns>
+ /// <c>true</c> if the current instance contains the specified sequence; otherwise, <c>false</c>.
+ /// </returns>
+ public virtual bool Contains(T[] sequence)
+ {
+ Contract.Requires(sequence.Length > 0);
+ if (this.Root == null) return false;
+
+ Node cur = this.Root;
+ for (int i = 0; i < sequence.Length; i++)
+ {
+ int cmp = cur.Value.CompareTo(sequence[i]);
+ if (i == sequence.Length - 1 && cmp == 0) return cur.IsEnd;
+ cur = cur.GetNextFor(cmp);
+ if (cmp != 0) i--;
+ if (cur == null) return false;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Gets all the sequences starting with the specified elements.
+ /// </summary>
+ /// <param name="sequence">The sequence of starting elements.</param>
+ /// <returns>The sequences starting with the specified elements.</returns>
+ public virtual IEnumerable<T[]> StartingWith(T[] sequence)
+ {
+ Contract.Requires(sequence.Length > 0);
+ if (this.Root == null) yield break;
+
+ Node cur = this.Root;
+ for (int i = 0; i < sequence.Length; i++)
+ {
+ int cmp = cur.Value.CompareTo(sequence[i]);
+ if (i == sequence.Length - 1 && cmp == 0) break;
+ cur = cur.GetNextFor(cmp);
+ if (cmp != 0) i--;
+ if (cur == null) yield break;
+ }
+
+ if (cur.IsEnd) yield return sequence;
+ if (cur.Below != null) foreach (T[] seq in this.StartingWith(sequence, cur.Below)) yield return seq;
+ }
+
+ private IEnumerable<T[]> StartingWith(T[] sequence, Node cur)
+ {
+ T[] seq = new T[sequence.Length + 1];
+ Array.Copy(sequence, seq, sequence.Length);
+ seq[sequence.Length] = cur.Value;
+
+ if (cur.IsEnd) yield return seq;
+ if (cur.Left != null) foreach (T[] s in this.StartingWith(sequence, cur.Left)) yield return s;
+ if (cur.Below != null) foreach (T[] s in this.StartingWith(seq, cur.Below)) yield return s;
+ if (cur.Right != null) foreach (T[] s in this.StartingWith(sequence, cur.Right)) yield return s;
+ }
+
+ /// <summary>
+ /// Gets the enumerator.
+ /// </summary>
+ /// <returns>The enumerator.</returns>
+ public IEnumerator<T[]> GetEnumerator()
+ {
+ foreach (var item in this.Items)
+ {
+ yield return item;
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return this.GetEnumerator();
+ }
+ }
+}
View
133 SharpBag/Collections/TernaryStringSearchTree.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SharpBag.Collections
+{
+ /// <summary>
+ /// A ternary string-search tree.
+ /// </summary>
+ public class TernaryStringSearchTree : TernarySearchTree<char>, IEnumerable<string>
+ {
+ /// <summary>
+ /// Gets a value indicating whether the search tree is case sensitive.
+ /// </summary>
+ /// <value>
+ /// Whether the search tree is case sensitive.
+ /// </value>
+ public bool CaseSensitive { get; private set; }
+
+ /// <summary>
+ /// Gets the items.
+ /// </summary>
+ public new IEnumerable<string> Items
+ {
+ get
+ {
+ foreach (var item in base.Items)
+ {
+ yield return new String(item);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TernaryStringSearchTree"/> class.
+ /// </summary>
+ /// <param name="caseSensitive">Whether the search tree is case sensitive.</param>
+ public TernaryStringSearchTree(bool caseSensitive = true)
+ {
+ this.CaseSensitive = caseSensitive;
+ }
+
+ private char[] ToUpper(char[] sequence)
+ {
+ char[] upperSequence = new char[sequence.Length];
+ for (int i = 0; i < sequence.Length; i++) upperSequence[i] = Char.ToUpper(sequence[i]);
+ return upperSequence;
+ }
+
+ /// <summary>
+ /// Adds the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence.</param>
+ /// <returns>Whether the sequence was new.</returns>
+ public bool Add(string sequence)
+ {
+ return base.Add(this.CaseSensitive ? sequence.ToCharArray() : this.ToUpper(sequence.ToCharArray()));
+ }
+
+ /// <summary>
+ /// Adds the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence.</param>
+ /// <returns>Whether the sequence was new.</returns>
+ public override bool Add(char[] sequence)
+ {
+ return base.Add(this.CaseSensitive ? sequence : this.ToUpper(sequence));
+ }
+
+ /// <summary>
+ /// Determines whether the current instance contains the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence.</param>
+ /// <returns>
+ /// <c>true</c> if the current instance contains the specified sequence; otherwise, <c>false</c>.
+ /// </returns>
+ public bool Contains(string sequence)
+ {
+ return base.Contains(this.CaseSensitive ? sequence.ToCharArray() : this.ToUpper(sequence.ToCharArray()));
+ }
+
+ /// <summary>
+ /// Determines whether the current instance contains the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence.</param>
+ /// <returns>
+ /// <c>true</c> if the current instance contains the specified sequence; otherwise, <c>false</c>.
+ /// </returns>
+ public override bool Contains(char[] sequence)
+ {
+ return base.Contains(this.CaseSensitive ? sequence : this.ToUpper(sequence));
+ }
+
+ /// <summary>
+ /// Gets all the sequences starting with the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence of starting elements.</param>
+ /// <returns>The sequences starting with the specified sequence.</returns>
+ public IEnumerable<string> StartingWith(string sequence)
+ {
+ return base.StartingWith(this.CaseSensitive ? sequence.ToCharArray() : this.ToUpper(sequence.ToCharArray())).Select(i => new String(i));
+ }
+
+ /// <summary>
+ /// Gets all the sequences starting with the specified sequence.
+ /// </summary>
+ /// <param name="sequence">The sequence of starting elements.</param>
+ /// <returns>The sequences starting with the specified sequence.</returns>
+ public new IEnumerable<string> StartingWith(char[] sequence)
+ {
+ return base.StartingWith(this.CaseSensitive ? sequence : this.ToUpper(sequence)).Select(i => new String(i));
+ }
+
+ /// <summary>
+ /// Gets the enumerator.
+ /// </summary>
+ /// <returns>The enumerator.</returns>
+ public new IEnumerator<string> GetEnumerator()
+ {
+ foreach (var item in this.Items)
+ {
+ yield return item;
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return this.GetEnumerator();
+ }
+ }
+}
View
8 SharpBag/SharpBag.csproj
@@ -75,6 +75,8 @@
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Collections\TernarySearchTree.cs" />
+ <Compile Include="Collections\TernaryStringSearchTree.cs" />
<Compile Include="DisposableAction.cs" />
<Compile Include="CollectionExtensions.cs" />
<Compile Include="Collections\BinaryHeap.cs" />
@@ -112,10 +114,10 @@
<Compile Include="Math\ForFraction\ForBigInteger\Matrix.cs" />
<Compile Include="Math\ForFraction\ForBigInteger\Vector.cs" />
<Compile Include="Math\ForBigInteger\Fraction.cs" />
- <Compile Include="Math\ForBigInteger\Polynomial.cs" />
- <Compile Include="Math\ForComplex\Polynomial.cs" />
+ <Compile Include="Math\ForBigInteger\Polynomial.cs" />
+ <Compile Include="Math\ForComplex\Polynomial.cs" />
<Compile Include="Math\ForFraction\ForInt32\Matrix.cs" />
- <Compile Include="Math\ForFraction\ForInt32\Vector.cs" />
+ <Compile Include="Math\ForFraction\ForInt32\Vector.cs" />
<Compile Include="Math\ForInt64\Polynomial.cs" />
<Compile Include="Math\ForInt32\Polynomial.cs" />
<Compile Include="Math\Geometry\Circle.cs" />
View
BIN  SharpBag/bin/Release/CodeContracts/SharpBag.Contracts.dll
Binary file not shown
View
BIN  SharpBag/bin/Release/SharpBag.dll
Binary file not shown
View
126 SharpBag/bin/Release/SharpBagDocs.xml
@@ -12057,5 +12057,131 @@
The default value.
</summary>
</member>
+ <member name="T:SharpBag.Collections.TernarySearchTree`1">
+ <summary>
+ A ternary search tree.
+ </summary>
+ <typeparam name="T">The type of items in the tree.</typeparam>
+ </member>
+ <member name="M:SharpBag.Collections.TernarySearchTree`1.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:SharpBag.Collections.TernarySearchTree`1"/> class.
+ </summary>
+ </member>
+ <member name="M:SharpBag.Collections.TernarySearchTree`1.Add(`0[])">
+ <summary>
+ Adds the specified sequence.
+ </summary>
+ <param name="sequence">The sequence.</param>
+ <returns>Whether the sequence was new.</returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernarySearchTree`1.Contains(`0[])">
+ <summary>
+ Determines whether the current instance contains the specified sequence.
+ </summary>
+ <param name="sequence">The sequence.</param>
+ <returns>
+ <c>true</c> if the current instance contains the specified sequence; otherwise, <c>false</c>.
+ </returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernarySearchTree`1.StartingWith(`0[])">
+ <summary>
+ Gets all the sequences starting with the specified elements.
+ </summary>
+ <param name="sequence">The sequence of starting elements.</param>
+ <returns>The sequences starting with the specified elements.</returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernarySearchTree`1.GetEnumerator">
+ <summary>
+ Gets the enumerator.
+ </summary>
+ <returns>The enumerator.</returns>
+ </member>
+ <member name="P:SharpBag.Collections.TernarySearchTree`1.Count">
+ <summary>
+ Gets the item count.
+ </summary>
+ </member>
+ <member name="P:SharpBag.Collections.TernarySearchTree`1.Items">
+ <summary>
+ Gets the items.
+ </summary>
+ </member>
+ <member name="T:SharpBag.Collections.TernaryStringSearchTree">
+ <summary>
+ A ternary string-search tree.
+ </summary>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.#ctor(System.Boolean)">
+ <summary>
+ Initializes a new instance of the <see cref="T:SharpBag.Collections.TernaryStringSearchTree"/> class.
+ </summary>
+ <param name="caseSensitive">Whether the search tree is case sensitive.</param>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.Add(System.String)">
+ <summary>
+ Adds the specified sequence.
+ </summary>
+ <param name="sequence">The sequence.</param>
+ <returns>Whether the sequence was new.</returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.Add(System.Char[])">
+ <summary>
+ Adds the specified sequence.
+ </summary>
+ <param name="sequence">The sequence.</param>
+ <returns>Whether the sequence was new.</returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.Contains(System.String)">
+ <summary>
+ Determines whether the current instance contains the specified sequence.
+ </summary>
+ <param name="sequence">The sequence.</param>
+ <returns>
+ <c>true</c> if the current instance contains the specified sequence; otherwise, <c>false</c>.
+ </returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.Contains(System.Char[])">
+ <summary>
+ Determines whether the current instance contains the specified sequence.
+ </summary>
+ <param name="sequence">The sequence.</param>
+ <returns>
+ <c>true</c> if the current instance contains the specified sequence; otherwise, <c>false</c>.
+ </returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.StartingWith(System.String)">
+ <summary>
+ Gets all the sequences starting with the specified sequence.
+ </summary>
+ <param name="sequence">The sequence of starting elements.</param>
+ <returns>The sequences starting with the specified sequence.</returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.StartingWith(System.Char[])">
+ <summary>
+ Gets all the sequences starting with the specified sequence.
+ </summary>
+ <param name="sequence">The sequence of starting elements.</param>
+ <returns>The sequences starting with the specified sequence.</returns>
+ </member>
+ <member name="M:SharpBag.Collections.TernaryStringSearchTree.GetEnumerator">
+ <summary>
+ Gets the enumerator.
+ </summary>
+ <returns>The enumerator.</returns>
+ </member>
+ <member name="P:SharpBag.Collections.TernaryStringSearchTree.CaseSensitive">
+ <summary>
+ Gets a value indicating whether the search tree is case sensitive.
+ </summary>
+ <value>
+ Whether the search tree is case sensitive.
+ </value>
+ </member>
+ <member name="P:SharpBag.Collections.TernaryStringSearchTree.Items">
+ <summary>
+ Gets the items.
+ </summary>
+ </member>
</members>
</doc>
Please sign in to comment.
Something went wrong with that request. Please try again.