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

隨筆 - 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 鷹擊長空 閱讀(501) 評論(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>
            久久久777| 最新精品在线| 韩国三级电影一区二区| 国模私拍一区二区三区| 亚洲国产精品精华液2区45| 91久久夜色精品国产网站| 一本综合久久| 久久精品人人做人人综合| 老司机免费视频一区二区| 亚洲国产一区在线| 夜夜精品视频| 久久久国产一区二区| 欧美国内亚洲| 国产午夜久久| 中文国产一区| 久久综合九色99| 亚洲精品久久7777| 久久精品91久久久久久再现| 欧美大片在线观看一区二区| 国产精品一区二区久久久久| 亚洲国产欧美在线人成| 亚洲免费人成在线视频观看| 麻豆国产精品一区二区三区| 99这里有精品| 免费久久99精品国产自| 国产欧美日韩精品a在线观看| 亚洲第一色在线| 欧美亚洲视频一区二区| 亚洲狠狠婷婷| 久久理论片午夜琪琪电影网| 国产精品久久久久免费a∨大胸| 1204国产成人精品视频| 欧美在线视频免费播放| 亚洲精品久久久久久久久久久 | 亚洲午夜精品久久久久久浪潮| 久久精品视频在线看| 一本大道久久精品懂色aⅴ| 麻豆久久精品| 精品福利电影| 久久久国产一区二区| 一区二区三区免费观看| 欧美国产三区| 精品91在线| 久久婷婷国产麻豆91天堂| 99一区二区| 欧美性开放视频| 日韩一级在线观看| 91久久香蕉国产日韩欧美9色 | 欧美成人免费一级人片100| 亚洲免费一区二区| 国产精品久久久久久福利一牛影视| 亚洲国产精品va在线看黑人| 开心色5月久久精品| 久久丁香综合五月国产三级网站| 国产精品视频九色porn| 亚洲欧美精品suv| 一本色道久久综合亚洲精品小说| 欧美激情在线有限公司| 亚洲毛片在线观看.| 亚洲激情综合| 欧美精品久久久久久| 亚洲麻豆国产自偷在线| 亚洲乱码国产乱码精品精98午夜| 欧美久久一区| 亚洲午夜久久久久久久久电影院| 亚洲精品一品区二品区三品区| 欧美成人午夜剧场免费观看| 日韩视频在线免费| 亚洲精选中文字幕| 欧美性久久久| 久久久精品视频成人| 久久视频精品在线| 91久久精品www人人做人人爽 | 一本一道久久综合狠狠老精东影业| 亚洲级视频在线观看免费1级| 欧美日本国产在线| 午夜国产精品视频| 欧美在线综合| 亚洲精品日产精品乱码不卡| 一区二区不卡在线视频 午夜欧美不卡'| 欧美色图五月天| 久久久精品久久久久| 蜜桃久久精品乱码一区二区| 在线午夜精品| 欧美一级午夜免费电影| 亚洲激情在线观看| 国产精品99久久不卡二区| 国内精品伊人久久久久av一坑| 女女同性女同一区二区三区91| 欧美极品欧美精品欧美视频| 久久aⅴ国产欧美74aaa| 欧美sm重口味系列视频在线观看| 亚洲视频在线一区| 久久国产福利| 99精品热视频只有精品10| 午夜精彩视频在线观看不卡 | 欧美日韩三级在线| 久久久久一本一区二区青青蜜月| 欧美大学生性色视频| 欧美在线视频a| 欧美黄污视频| 久久亚洲午夜电影| 欧美视频一区二区三区…| 你懂的一区二区| 国产精品丝袜xxxxxxx| 亚洲福利视频网站| 国产午夜精品福利| 亚洲手机在线| 妖精视频成人观看www| 久久免费视频网| 久久久www| 国产精品丝袜白浆摸在线| 亚洲精品日本| 亚洲全黄一级网站| 久久久亚洲人| 久久久午夜视频| 国产欧美一区二区色老头| 99综合视频| 亚洲天堂网在线观看| 欧美极品在线播放| 亚洲国产高清视频| 一区二区在线视频播放| 欧美中日韩免费视频| 久久成人18免费网站| 国产精品久久久久久久久动漫| 亚洲黄色在线看| 亚洲人午夜精品| 欧美不卡视频一区| 欧美国产日韩精品| 亚洲第一色在线| 免费视频最近日韩| 亚洲国产高清一区| 99国产精品99久久久久久粉嫩| 你懂的视频一区二区| 欧美电影免费网站| 亚洲人成在线播放网站岛国| 美女福利精品视频| 亚洲福利视频网站| 一区二区三区色| 欧美四级在线| 亚洲在线观看视频| 久久精品一区二区三区四区| 激情文学综合丁香| 欧美成人国产| 99精品福利视频| 亚欧成人精品| 亚洲成人在线| 欧美ed2k| 在线天堂一区av电影| 午夜精品久久久久| 黑人巨大精品欧美黑白配亚洲| 久久精品99| 亚洲激情小视频| 午夜精品久久久久久久99水蜜桃 | 亚洲国产精品一区二区久| 欧美v国产在线一区二区三区| 亚洲国产成人tv| 亚洲综合电影| 国内外成人在线| 欧美激情欧美激情在线五月| 一本色道久久综合亚洲精品按摩 | 亚洲第一天堂av| 亚洲一区二区少妇| 国产一区日韩二区欧美三区| 久久综合国产精品| 日韩一二三在线视频播| 久久精品女人的天堂av| 亚洲国产欧美久久| 国产精品免费看片| 久久色中文字幕| 亚洲午夜精品视频| 免费成人你懂的| 亚洲欧美成人精品| 亚洲第一精品福利| 国产乱码精品一区二区三区忘忧草 | 好吊视频一区二区三区四区 | 一区二区三区久久网| 欧美成人国产一区二区 | 国产精品福利片| 久久亚洲春色中文字幕| 亚洲一区二区三区777| 免费在线播放第一区高清av| 午夜激情一区| 夜夜爽av福利精品导航| 在线播放豆国产99亚洲| 国产精品免费小视频| 欧美日韩成人一区二区| 久久精品综合| 亚洲欧美日韩国产综合| 99精品视频免费在线观看| 欧美成人按摩| 久久综合网hezyo| 久久aⅴ国产欧美74aaa| 亚洲一区二区三| 亚洲免费高清| 亚洲人成人一区二区三区| 黄色一区二区三区四区| 国产欧美日韩| 国产日韩亚洲欧美| 国产午夜亚洲精品不卡|