青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 42  文章 - 3  trackbacks - 0
<2012年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用鏈接

留言簿(2)

隨筆檔案

文章檔案

網頁收藏

搜索

  •  

最新評論

閱讀排行榜

評論排行榜


The original post is
http://igoro.com/archive/efficient-auto-complete-with-a-ternary-search-tree/

Over the past couple of years, auto-complete has popped up all over the web. Facebook, YouTube, Google, Bing, MSDN, LinkedIn and lots of other websites all try to complete your phrase as soon as you start typing.

Auto-complete definitely makes for a nice user experience, but it can be a challenge to implement efficiently. In many cases, an efficient implementation requires the use of interesting algorithms and data structures. In this blog post, I will describe one simple data structure that can be used to implement auto-complete: a ternary search tree.

Trie: simple but space-inefficient

Before discussing ternary search trees, let’s take a look at a simple data structure that supports a fast auto-complete lookup but needs too much memory: a trie. A trie is a tree-like data structure in which each node contains an array of pointers, one pointer for each character in the alphabet. Starting at the root node, we can trace a word by following pointers corresponding to the letters in the target word.

Each node could be implemented like this in C#:

class TrieNode
{
public const int ALPHABET_SIZE = 26;
public TrieNode[] m_pointers = new TrieNode[ALPHABET_SIZE];
public bool m_endsString = false;
}

Here is a trie that stores words AB, ABBA, ABCD, and BCD. Nodes that terminate words are marked yellow:

 

gif_1

 

Implementing auto complete using a trie is easy. We simply trace pointers to get to a node that represents the string the user entered. By exploring the trie from that node down, we can enumerate all strings that complete user’s input.

But, a trie has a major problem that you can see in the diagram above. The diagram only fits on the page because the trie only supports four letters {A,B,C,D}. If we needed to support all 26 English letters, each node would have to store 26 pointers. And, if we need to support international characters, punctuation, or distinguish between lowercase and uppercase characters, the memory usage grows becomes untenable.

Our problem has to do with the memory taken up by all the null pointers stored in the node arrays. We could consider using a different data structure in each node, such as a hash map. However, managing thousands and thousands of hash maps is generally not a good idea, so let’s take a look at a better solution.

Ternary search tree to the rescue

A ternary tree is a data structure that solves the memory problem of tries in a more clever way. To avoid the memory occupied by unnecessary pointers, each trie node is represented as a tree-within-a-tree rather than as an array. Each non-null pointer in the trie node gets its own node in a ternary search tree.

For example, the trie from the example above would be represented in the following way as a ternary search tree:

image

The ternary search tree contains three types of arrows. First, there are arrows that correspond to arrows in the corresponding trie, shown as dashed down-arrows. Traversing a down-arrow corresponds to “matching” the character from which the arrow starts. The left- and right- arrow are traversed when the current character does not match the desired character at the current position. We take the left-arrow if the character we are looking for is alphabetically before the character in the current node, and the right-arrow in the opposite case.

For example, green arrows show how we’d confirm that the ternary tree contains string ABBA:

 image

And this is how we’d find that the ternary string does not contain string ABD:

image 

Ternary search tree on a server

On the web, a significant chunk of the auto-complete work has to be done by the server. Often, the set of possible completions is large, so it is usually not a good idea to download all of it to the client. Instead, the ternary tree is stored on the server, and the client will send prefix queries to the server.

The client will send a query for words starting with “bin” to the server:

  image

And the server responds with a list of possible words:

image 

Implementation

Here is a simple ternary search tree implementation in C#:

public class TernaryTree
{
private Node m_root = null;
private void Add(string s, int pos, ref Node node)
{
if (node == null) { node = new Node(s[pos], false); }
if (s[pos] < node.m_char) { Add(s, pos, ref node.m_left); }
else if (s[pos] > node.m_char) { Add(s, pos, ref node.m_right); }
else
{
if (pos + 1 == s.Length) { node.m_wordEnd = true; }
else { Add(s, pos + 1, ref node.m_center); }
}
}
public void Add(string s)
{
if (s == null || s == "") throw new ArgumentException();
Add(s, 0, ref m_root);
}
public bool Contains(string s)
{
if (s == null || s == "") throw new ArgumentException();
int pos = 0;
Node node = m_root;
while (node != null)
{
int cmp = s[pos] - node.m_char;
if (s[pos] < node.m_char) { node = node.m_left; }
else if (s[pos] > node.m_char) { node = node.m_right; }
else
{
if (++pos == s.Length) return node.m_wordEnd;
node = node.m_center;
}
}
return false;
}
}

And here is the Node class:

class Node
{
internal char m_char;
internal Node m_left, m_center, m_right;
internal bool m_wordEnd;
public Node(char ch, bool wordEnd)
{
m_char = ch;
m_wordEnd = wordEnd;
}
}

Remarks

For best performance, strings should be inserted into the ternary tree in a random order. In particular, do not insert strings in the alphabetical order. Each mini-tree that corresponds to a single trie node would degenerate into a linked list, significantly increasing the cost of lookups. Of course, more complex self-balancing ternary trees can be implemented as well.

And, don’t use a fancier data structure than you have to. If you only have a relatively small set of candidate words (say on the order of hundreds) a brute-force search should be fast enough.

Further reading

Another article on tries is available on DDJ (careful, their implementation assumes that no word is a prefix of another):

http://www.ddj.com/windows/184410528

If you like this article, also check out these posts on my blog:


posted on 2012-06-25 23:26 鷹擊長空 閱讀(495) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产一区视频在线观看免费| 国产视频精品网| 精品99一区二区| 久久久久久综合| 久久嫩草精品久久久精品一| 在线视频观看日韩| 亚洲国产经典视频| 欧美精品三级日韩久久| 亚洲视频电影图片偷拍一区| 亚洲一卡二卡三卡四卡五卡| 国产日韩欧美一二三区| 久久人人看视频| 美女尤物久久精品| 在线视频欧美日韩精品| 亚洲制服欧美中文字幕中文字幕| 国产美女精品免费电影| 久久这里有精品视频| 奶水喷射视频一区| 亚洲一区二区日本| 久久不射中文字幕| 亚洲精品自在久久| 亚洲综合日韩中文字幕v在线| 黄色日韩网站| 亚洲日本成人| 国产日韩欧美二区| 亚洲高清毛片| 国产精品亚洲综合| 亚洲电影激情视频网站| 国产精品国产三级国产普通话蜜臀 | 午夜精品久久久久久久99黑人| 国产一区二区在线免费观看| 亚洲第一狼人社区| 国产欧美综合一区二区三区| 欧美成人午夜激情视频| 国产精品高清在线| 亚洲福利免费| 国产亚洲欧美另类中文| 亚洲三级观看| 一区二区在线观看av| 在线视频欧美日韩| 91久久久久久| 久久电影一区| 香蕉久久夜色精品国产| 欧美大成色www永久网站婷| 欧美在线观看视频在线| 欧美日韩国产二区| 欧美99久久| 国产一二精品视频| 亚洲性视频网址| 亚洲狼人精品一区二区三区| 久久国产精品久久久久久久久久| 国产精品99久久久久久宅男| 免费在线欧美视频| 免费成人黄色| 在线观看精品一区| 欧美一区二区三区视频免费| 亚洲欧美日韩视频二区| 欧美日韩国产电影| 亚洲激情av在线| 亚洲国产精品电影在线观看| 久久久久高清| 噜噜噜在线观看免费视频日韩 | 性欧美18~19sex高清播放| 一区二区三区高清不卡| 欧美顶级大胆免费视频| 欧美激情亚洲国产| 亚洲日本在线视频观看| 欧美电影在线免费观看网站| 欧美激情一区二区三区蜜桃视频| 在线成人欧美| 免费视频一区二区三区在线观看| 欧美第十八页| 91久久久久久国产精品| 欧美国产精品日韩| 亚洲乱码国产乱码精品精可以看| 日韩午夜视频在线观看| 欧美三级精品| 亚洲一区欧美激情| 欧美中文字幕第一页| 精品动漫3d一区二区三区免费版 | 亚洲欧美日韩在线一区| 久久精品理论片| 影音欧美亚洲| 欧美大片在线观看| 一本久久a久久免费精品不卡| 亚洲综合精品一区二区| 国产精品综合久久久| 欧美专区中文字幕| 欧美国产日产韩国视频| av成人激情| 国产精品丝袜xxxxxxx| 久久成人免费| 亚洲国产精品va在线看黑人| 亚洲综合另类| 伊人影院久久| 欧美日韩亚洲一区二区三区在线 | 亚洲国产精品久久久久婷婷老年| 在线一区日本视频| 国产精品免费一区豆花| 久久另类ts人妖一区二区| 亚洲国产视频直播| 欧美一二三视频| 亚洲激情偷拍| 国产精品一区二区在线观看不卡| 久久成人精品| 日韩一区二区精品在线观看| 久久精品一二三| aa级大片欧美| 激情综合视频| 国产精品第十页| 欧美大片专区| 久久xxxx精品视频| 中文高清一区| 亚洲电影天堂av| 久久久久久久久伊人| 亚洲桃色在线一区| 亚洲国产日韩欧美一区二区三区| 欧美色综合网| 欧美高清视频一区二区三区在线观看 | 中日韩视频在线观看| 激情小说亚洲一区| 国产精品国产馆在线真实露脸| 久热精品视频| 久久国产视频网| 亚洲嫩草精品久久| 日韩视频一区| 亚洲人成免费| 欧美激情视频一区二区三区在线播放| 欧美有码视频| 亚洲自拍偷拍麻豆| 在线视频一区二区| 亚洲日本va午夜在线影院| 国产午夜精品在线| 国产精品免费aⅴ片在线观看| 欧美国产精品劲爆| 欧美成人精品h版在线观看| 久久精品日韩欧美| 久久av一区二区三区漫画| 亚洲一区二区三区四区五区午夜| 亚洲精品中文在线| 亚洲精品国产精品国自产观看浪潮| 免费日韩av片| 久久亚洲私人国产精品va| 久久久久久国产精品一区| 欧美影院久久久| 欧美一区二区三区四区夜夜大片| 亚洲一区国产| 亚洲一区二区毛片| 亚洲综合另类| 欧美在线观看视频在线| 欧美一区二区在线视频| 久久国产手机看片| 久久久国产91| 久久综合色8888| 老色鬼久久亚洲一区二区 | 亚洲无限av看| 亚洲一区二区免费看| 亚洲欧美电影在线观看| 欧美亚洲免费在线| 久久国产精品亚洲77777| 久久精品99久久香蕉国产色戒| 久久国产视频网| 老司机午夜精品视频在线观看| 欧美不卡视频一区| 亚洲精品看片| 亚洲欧美成aⅴ人在线观看| 午夜精品成人在线视频| 久久久国产精品一区| 久久综合999| 欧美性视频网站| 国产亚洲欧美一区二区| 最新亚洲激情| 亚洲综合欧美日韩| 另类激情亚洲| 一本色道久久综合| 欧美一区二视频| 欧美国产大片| 国产精品一区免费视频| 亚洲二区免费| 新狼窝色av性久久久久久| 欧美sm视频| 亚洲一区二三| 欧美大胆人体视频| 国产日本欧美一区二区三区在线| 亚洲高清自拍| 午夜在线视频一区二区区别| 免播放器亚洲| 中文在线资源观看网站视频免费不卡 | 日韩午夜在线视频| 久久精品成人| 国产精品久久久久久久久久三级 | 国产欧美精品在线播放| 亚洲激情视频在线播放| 欧美在线免费| 亚洲日本电影| 免费不卡中文字幕视频| 国产日韩欧美精品一区| 中日韩午夜理伦电影免费| 欧美a一区二区| 欧美一级成年大片在线观看|