4 people like it.
Like the snippet!
Type-a-head search tree for strings
This is a search tree for strings I've built for work to back fast type-a-head for AJAX forms, it could be made million times more space efficient but there was no real need for it so.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
|
module SearchTree =
open System
let inline private ($) a b = b a
type T<'a> = {
Map : Map<char, T<'a>>
Values : 'a list
}
type TO<'a> = T<'a> option
let empty<'a> : TO<'a> = None
let insert (s:string) value (t:TO<_>) =
let rec insert (i:int) (t:TO<_>) =
if i < s.Length then
let c = s.[i]
match t with
| None ->
let subNode = None $ insert (i+1)
let map = Map.empty $ Map.add c subNode
{Map=map; Values=[value]}
| Some node ->
match node.Map $ Map.tryFind c with
| None ->
let subNode = None $ insert (i+1)
let map = node.Map $ Map.add c subNode
{Map=map; Values=value::node.Values}
| Some subNode ->
let subNode = Some subNode $ insert (i+1)
let map = node.Map $ Map.add c subNode
{Map=map; Values=value::node.Values}
else
{Map=Map.empty; Values=[value]}
t $ insert 0 $ Some
let find (s:string) (t:TO<_>) =
let rec find (i:int) (t:TO<_>) =
if i < s.Length then
let c = s.[i]
match t with
| None -> []
| Some node ->
node.Map $ Map.tryFind c $ find (i+1)
else
match t with
| None -> []
| Some node -> node.Values
t $ find 0
//Example
open System
let rnd = Random()
let randomChar () =
Math.Floor((rnd.NextDouble() * 26.0) + 65.0) |> char
let randomString () =
let sb = new Text.StringBuilder()
for i = 0 to 20 do
sb.Append(randomChar()) |> ignore
sb.ToString()
let mutable tree =
SearchTree.empty<int>
for i = 0 to 1000000 do
tree <- tree |> SearchTree.insert (randomString()) i
|
namespace System
val a : 'a
val b : ('a -> 'b)
type T<'a> =
{Map: Map<char,T<'a>>;
Values: 'a list;}
Full name: Script.SearchTree.T<_>
Multiple items
T.Map: Map<char,T<'a>>
--------------------
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
Multiple items
val char : value:'T -> char (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.char
--------------------
type char = Char
Full name: Microsoft.FSharp.Core.char
T.Values: 'a list
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
type TO<'a> = T<'a> option
Full name: Script.SearchTree.TO<_>
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
val empty<'a> : TO<'a>
Full name: Script.SearchTree.empty
union case Option.None: Option<'T>
val insert : s:string -> value:'a -> t:TO<'a> -> T<'a> option
Full name: Script.SearchTree.insert
val s : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
val value : 'a
val t : TO<'a>
val insert : (int -> TO<'a> -> T<'a>)
val i : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
property String.Length: int
val c : char
val subNode : T<'a>
val map : Map<char,T<'a>>
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val empty<'Key,'T (requires comparison)> : Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.empty
val add : key:'Key -> value:'T -> table:Map<'Key,'T> -> Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.add
union case Option.Some: Value: 'T -> Option<'T>
val node : T<'a>
T.Map: Map<char,T<'a>>
val tryFind : key:'Key -> table:Map<'Key,'T> -> 'T option (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.tryFind
val find : s:string -> t:TO<'a> -> 'a list
Full name: Script.SearchTree.find
val find : (int -> TO<'b> -> 'b list)
val t : TO<'b>
val node : T<'b>
T.Map: Map<char,T<'b>>
T.Values: 'b list
val rnd : Random
Full name: Script.rnd
Multiple items
type Random =
new : unit -> Random + 1 overload
member Next : unit -> int + 2 overloads
member NextBytes : buffer:byte[] -> unit
member NextDouble : unit -> float
Full name: System.Random
--------------------
Random() : unit
Random(Seed: int) : unit
val randomChar : unit -> char
Full name: Script.randomChar
type Math =
static val PI : float
static val E : float
static member Abs : value:sbyte -> sbyte + 6 overloads
static member Acos : d:float -> float
static member Asin : d:float -> float
static member Atan : d:float -> float
static member Atan2 : y:float * x:float -> float
static member BigMul : a:int * b:int -> int64
static member Ceiling : d:decimal -> decimal + 1 overload
static member Cos : d:float -> float
...
Full name: System.Math
Math.Floor(d: float) : float
Math.Floor(d: decimal) : decimal
Random.NextDouble() : float
val randomString : unit -> string
Full name: Script.randomString
val sb : Text.StringBuilder
namespace System.Text
Multiple items
type StringBuilder =
new : unit -> StringBuilder + 5 overloads
member Append : value:string -> StringBuilder + 18 overloads
member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads
member AppendLine : unit -> StringBuilder + 1 overload
member Capacity : int with get, set
member Chars : int -> char with get, set
member Clear : unit -> StringBuilder
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EnsureCapacity : capacity:int -> int
member Equals : sb:StringBuilder -> bool
...
Full name: System.Text.StringBuilder
--------------------
Text.StringBuilder() : unit
Text.StringBuilder(capacity: int) : unit
Text.StringBuilder(value: string) : unit
Text.StringBuilder(value: string, capacity: int) : unit
Text.StringBuilder(capacity: int, maxCapacity: int) : unit
Text.StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit
Text.StringBuilder.Append(value: char []) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: obj) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: uint64) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: uint32) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: uint16) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: decimal) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: float) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: float32) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: int64) : Text.StringBuilder
(+0 other overloads)
Text.StringBuilder.Append(value: int) : Text.StringBuilder
(+0 other overloads)
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
Text.StringBuilder.ToString() : string
Text.StringBuilder.ToString(startIndex: int, length: int) : string
val mutable tree : SearchTree.TO<int>
Full name: Script.tree
module SearchTree
from Script
val empty<'a> : SearchTree.TO<'a>
Full name: Script.SearchTree.empty
val insert : s:string -> value:'a -> t:SearchTree.TO<'a> -> SearchTree.T<'a> option
Full name: Script.SearchTree.insert
More information