<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Ternary Search Tries</title>
	<atom:link href="http://programmingpraxis.com/2009/06/05/ternary-search-tries/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmingpraxis.com/2009/06/05/ternary-search-tries/</link>
	<description>A collection of etudes, updated weekly, for the education and enjoyment of the savvy programmer</description>
	<lastBuildDate>Sat, 11 Feb 2012 09:48:16 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: Vikas Tandi</title>
		<link>http://programmingpraxis.com/2009/06/05/ternary-search-tries/#comment-2974</link>
		<dc:creator><![CDATA[Vikas Tandi]]></dc:creator>
		<pubDate>Wed, 04 May 2011 09:49:04 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=508#comment-2974</guid>
		<description><![CDATA[implemented in C
[sourcecode lang=&quot;cpp&quot;]
#include &lt;stdlib.h&gt;

typedef struct TernaryTrieNode
{
	char c;
	struct TernaryTrieNode *left;
	struct TernaryTrieNode *mid;
	struct TernaryTrieNode *right;
}TernaryTrie;

static TernaryTrie* create_node(char c);
static int TernaryTrie_search_imp(TernaryTrie *p, char *s, int pos);
static TernaryTrie* TernaryTrie_insert_imp(TernaryTrie *p, char *s, int pos);

TernaryTrie* TernaryTrie_init()
{
	TernaryTrie *head;

	head = create_node(0);
	if(head == NULL)
		return NULL;

	head-&gt;left = head-&gt;right = head;
	return head;
}

int TernaryTrie_search(TernaryTrie *p, char *s)
{
	if(s == NULL &#124;&#124; s[0] == &#039;&#092;&#048;&#039;)
		return 0;
	return TernaryTrie_search_imp(p-&gt;mid, s, 0);
}

static int TernaryTrie_search_imp(TernaryTrie *p, char *s, int pos)
{
	if(p == NULL)
		return 0;
	if(s[pos] == &#039;&#092;&#048;&#039;)
		return 1;
	if(s[pos] &lt; p-&gt;c)
		return TernaryTrie_search_imp(p-&gt;left, s, pos);
	if(s[pos] == p-&gt;c)
		return TernaryTrie_search_imp(p-&gt;mid, s, pos+1);
	if(s[pos] &gt; p-&gt;c)
		return TernaryTrie_search_imp(p-&gt;right, s, pos);
}

TernaryTrie* TernaryTrie_insert(TernaryTrie *p, char *s)
{
	if(s == NULL &#124;&#124; s[0] == &#039;&#092;&#048;&#039;)
		return p;
	p-&gt;mid = TernaryTrie_insert_imp(p-&gt;mid, s, 0);
	return p;
}

static TernaryTrie* TernaryTrie_insert_imp(TernaryTrie *p, char *s, int pos)
{
	if(p == NULL)
	{
		p = create_node(s[pos]);
		if(p == NULL)
			return NULL;
	}
	if(s[pos] == &#039;&#092;&#048;&#039;)
		return p;

	if(s[pos] &lt; p-&gt;c)
		p-&gt;left = TernaryTrie_insert_imp(p-&gt;left, s, pos);
	if(s[pos] == p-&gt;c)
		p-&gt;mid = TernaryTrie_insert_imp(p-&gt;mid, s, pos+1);
	if(s[pos] &gt; p-&gt;c)
		p-&gt;right = TernaryTrie_insert_imp(p-&gt;right, s, pos);

	return p;
}

static TernaryTrie* create_node(char c)
{
	TernaryTrie *p;

	p = (TernaryTrie*)malloc(sizeof(*p));
	if(p == NULL)
		return NULL;

	p-&gt;c = c;
	p-&gt;left = p-&gt;right = p-&gt;mid = NULL;
	return p;
}
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>implemented in C</p>
<pre class="brush: cpp;">
#include &lt;stdlib.h&gt;

typedef struct TernaryTrieNode
{
	char c;
	struct TernaryTrieNode *left;
	struct TernaryTrieNode *mid;
	struct TernaryTrieNode *right;
}TernaryTrie;

static TernaryTrie* create_node(char c);
static int TernaryTrie_search_imp(TernaryTrie *p, char *s, int pos);
static TernaryTrie* TernaryTrie_insert_imp(TernaryTrie *p, char *s, int pos);

TernaryTrie* TernaryTrie_init()
{
	TernaryTrie *head;

	head = create_node(0);
	if(head == NULL)
		return NULL;

	head-&gt;left = head-&gt;right = head;
	return head;
}

int TernaryTrie_search(TernaryTrie *p, char *s)
{
	if(s == NULL || s[0] == '&#092;&#048;')
		return 0;
	return TernaryTrie_search_imp(p-&gt;mid, s, 0);
}

static int TernaryTrie_search_imp(TernaryTrie *p, char *s, int pos)
{
	if(p == NULL)
		return 0;
	if(s[pos] == '&#092;&#048;')
		return 1;
	if(s[pos] &lt; p-&gt;c)
		return TernaryTrie_search_imp(p-&gt;left, s, pos);
	if(s[pos] == p-&gt;c)
		return TernaryTrie_search_imp(p-&gt;mid, s, pos+1);
	if(s[pos] &gt; p-&gt;c)
		return TernaryTrie_search_imp(p-&gt;right, s, pos);
}

TernaryTrie* TernaryTrie_insert(TernaryTrie *p, char *s)
{
	if(s == NULL || s[0] == '&#092;&#048;')
		return p;
	p-&gt;mid = TernaryTrie_insert_imp(p-&gt;mid, s, 0);
	return p;
}

static TernaryTrie* TernaryTrie_insert_imp(TernaryTrie *p, char *s, int pos)
{
	if(p == NULL)
	{
		p = create_node(s[pos]);
		if(p == NULL)
			return NULL;
	}
	if(s[pos] == '&#092;&#048;')
		return p;

	if(s[pos] &lt; p-&gt;c)
		p-&gt;left = TernaryTrie_insert_imp(p-&gt;left, s, pos);
	if(s[pos] == p-&gt;c)
		p-&gt;mid = TernaryTrie_insert_imp(p-&gt;mid, s, pos+1);
	if(s[pos] &gt; p-&gt;c)
		p-&gt;right = TernaryTrie_insert_imp(p-&gt;right, s, pos);

	return p;
}

static TernaryTrie* create_node(char c)
{
	TernaryTrie *p;

	p = (TernaryTrie*)malloc(sizeof(*p));
	if(p == NULL)
		return NULL;

	p-&gt;c = c;
	p-&gt;left = p-&gt;right = p-&gt;mid = NULL;
	return p;
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2009/06/05/ternary-search-tries/#comment-160</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Fri, 05 Jun 2009 18:22:33 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=508#comment-160</guid>
		<description><![CDATA[My Haskell solution (see http://bonsaicode.wordpress.com/2009/06/05/programming-praxis-ternary-search-tries/ for a version with comments):

[sourcecode lang=&#039;css&#039;]
import Data.Char
import qualified Data.List.Key as K
import Prelude hiding (lookup)

data TernaryTrie k v = Empty &#124; Node { val :: Maybe v,
    split :: [k], lb :: !(TernaryTrie k v),
    eb :: !(TernaryTrie k v), gb :: !(TernaryTrie k v) }

lookup :: Ord k =&gt; [k] -&gt; TernaryTrie k v -&gt; Maybe v
lookup _      Empty = Nothing
lookup []     t     = val t
lookup (x:xs) t     = case compare [x] $ split t of
                           GT -&gt; lookup (x:xs) $ gb t
                           LT -&gt; lookup (x:xs) $ lb t
                           EQ -&gt; lookup xs     $ eb t

insert :: Ord k =&gt; [k] -&gt; v -&gt; TernaryTrie k v -&gt; TernaryTrie k v
insert k  v Empty = insert k v $
                    Node Nothing (take 1 k) Empty Empty Empty
insert [] v t     = t { val = Just v }
insert k  v t     = modify (flip insert v) k t

update :: Ord k =&gt; [k] -&gt; v -&gt; (v -&gt; v) -&gt;
          TernaryTrie k v -&gt; TernaryTrie k v
update k  v _ Empty = insert k v Empty
update [] v p t    = t { val = Just . maybe v p $ val t }
update k  v p t     = modify (\x -&gt; update x v p) k t

delete :: Ord k =&gt; [k] -&gt; TernaryTrie k v -&gt; TernaryTrie k v
delete _  Empty = Empty
delete [] t     = t { val = Nothing }
delete k  t     = modify delete k t

modify :: Ord k =&gt; ([k] -&gt; TernaryTrie k v -&gt; TernaryTrie k v) -&gt;
                   [k] -&gt; TernaryTrie k v -&gt; TernaryTrie k v
modify f k t = case compare (take 1 k) (split t) of
                    LT -&gt; t { lb = f (drop 0 k) $ lb t }
                    EQ -&gt; t { eb = f (drop 1 k) $ eb t }
                    GT -&gt; t { gb = f (drop 0 k) $ gb t }

enlist :: TernaryTrie k v -&gt; [([k], v)]
enlist = enlist&#039; [] where
    enlist&#039; _ Empty = []
    enlist&#039; k t     =
        maybe [] (\v -&gt; [(k, v)]) (val t) ++ enlist&#039; k (lb t) ++
        enlist&#039; (k ++ split t) (eb t) ++ enlist&#039; k (gb t)

main :: IO ()
main = print . take 25 . reverse . K.sort snd . enlist .
       foldl (\t k -&gt; update k 1 succ t) Empty .
       map (map toLower . filter isAlpha) . words =&lt;&lt;
       readFile &quot;bible.txt&quot;
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>My Haskell solution (see <a href="http://bonsaicode.wordpress.com/2009/06/05/programming-praxis-ternary-search-tries/" rel="nofollow">http://bonsaicode.wordpress.com/2009/06/05/programming-praxis-ternary-search-tries/</a> for a version with comments):</p>
<pre class="brush: css;">
import Data.Char
import qualified Data.List.Key as K
import Prelude hiding (lookup)

data TernaryTrie k v = Empty | Node { val :: Maybe v,
    split :: [k], lb :: !(TernaryTrie k v),
    eb :: !(TernaryTrie k v), gb :: !(TernaryTrie k v) }

lookup :: Ord k =&gt; [k] -&gt; TernaryTrie k v -&gt; Maybe v
lookup _      Empty = Nothing
lookup []     t     = val t
lookup (x:xs) t     = case compare [x] $ split t of
                           GT -&gt; lookup (x:xs) $ gb t
                           LT -&gt; lookup (x:xs) $ lb t
                           EQ -&gt; lookup xs     $ eb t

insert :: Ord k =&gt; [k] -&gt; v -&gt; TernaryTrie k v -&gt; TernaryTrie k v
insert k  v Empty = insert k v $
                    Node Nothing (take 1 k) Empty Empty Empty
insert [] v t     = t { val = Just v }
insert k  v t     = modify (flip insert v) k t

update :: Ord k =&gt; [k] -&gt; v -&gt; (v -&gt; v) -&gt;
          TernaryTrie k v -&gt; TernaryTrie k v
update k  v _ Empty = insert k v Empty
update [] v p t    = t { val = Just . maybe v p $ val t }
update k  v p t     = modify (\x -&gt; update x v p) k t

delete :: Ord k =&gt; [k] -&gt; TernaryTrie k v -&gt; TernaryTrie k v
delete _  Empty = Empty
delete [] t     = t { val = Nothing }
delete k  t     = modify delete k t

modify :: Ord k =&gt; ([k] -&gt; TernaryTrie k v -&gt; TernaryTrie k v) -&gt;
                   [k] -&gt; TernaryTrie k v -&gt; TernaryTrie k v
modify f k t = case compare (take 1 k) (split t) of
                    LT -&gt; t { lb = f (drop 0 k) $ lb t }
                    EQ -&gt; t { eb = f (drop 1 k) $ eb t }
                    GT -&gt; t { gb = f (drop 0 k) $ gb t }

enlist :: TernaryTrie k v -&gt; [([k], v)]
enlist = enlist' [] where
    enlist' _ Empty = []
    enlist' k t     =
        maybe [] (\v -&gt; [(k, v)]) (val t) ++ enlist' k (lb t) ++
        enlist' (k ++ split t) (eb t) ++ enlist' k (gb t)

main :: IO ()
main = print . take 25 . reverse . K.sort snd . enlist .
       foldl (\t k -&gt; update k 1 succ t) Empty .
       map (map toLower . filter isAlpha) . words =&lt;&lt;
       readFile &quot;bible.txt&quot;
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Programming Praxis &#8211; Ternary Search Tries &#171; Bonsai Code</title>
		<link>http://programmingpraxis.com/2009/06/05/ternary-search-tries/#comment-159</link>
		<dc:creator><![CDATA[Programming Praxis &#8211; Ternary Search Tries &#171; Bonsai Code]]></dc:creator>
		<pubDate>Fri, 05 Jun 2009 18:22:14 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=508#comment-159</guid>
		<description><![CDATA[[...] Praxis &#8211; Ternary Search&#160;Tries By Remco Niemeijer  Today’s Programming Praxis problem is about Ternary search tries, which are basically hashmaps of strings [...]]]></description>
		<content:encoded><![CDATA[<p>[...] Praxis &#8211; Ternary Search&nbsp;Tries By Remco Niemeijer  Today’s Programming Praxis problem is about Ternary search tries, which are basically hashmaps of strings [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

