CareerCup Trie Prefix Tree

265 篇文章 1 订阅
86 篇文章 0 订阅

Return a shortest prefix of <code>word</code> that is <em>not</em> a prefix of any word in the <code>list</code> 

e.g. 
word: cat, it has 4 prefixes: “”, “c”, “ca”, “cat” 
list: alpha, beta, cotton, delta, camera 

 

Result is “cat”

 

-----------------------------------------------------------------------------

Use unordered_map to replace array 

 

#include <stdio.h>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <iostream>
using namespace std;

class Trie
{
 public:
  int num;//to remember how many word can reach here,that is to say,prefix
  bool terminal;//If terminal==true ,the current point has no following point
  unordered_map<char, Trie*> son;
  Trie(bool terminal = false, int num = 1):terminal(terminal), num(num){
  }
};
typedef unordered_map<char, Trie*>::iterator IT;
Trie* BuildTrie()// create a new node
{
  Trie *root=new Trie(false, 0);
  return root;
}
void Insert(Trie* root, string& s)// insert a new word to Trie tree
{
  ++root->num;
  for(int i=0; i<s.length(); ++i)
  {
    if (root->son.find(s[i]) == root->son.end()) {
      Trie* tmp = new Trie(false, 1);
      root->son.insert(make_pair(s[i],tmp));
    }
    else
      root->son[s[i]]->num++;
    root = root->son[s[i]];
  }
  root->terminal=true;
}
void Delete(Trie *root)// delete the whole tree
{
  if(root!=NULL)  {
    for (IT it = root->son.begin(); it != root->son.end(); ++it) 
      Delete(it->second);
    delete root; 
    root=NULL;
  }
}
Trie* Find(Trie *root,string& s)//trie to find the current word
{
  for(int i=0;i<s.length();++i)
    if(root->son[s[i]]!=NULL)
      root=root->son[s[i]];
    else 
			return NULL;
  return root;
}
void ListAll(Trie *root,string& cur)
{
  if (root->terminal)
    cout << cur << endl;
  for (IT it = root->son.begin(); it != root->son.end(); ++it) {
    string next = cur + it->first;
    ListAll(it->second, next);
  }
}

void dfs(Trie* root, int K, string& cur, vector<string>& longeststr) {
  if (root->num < K)
    return;
  int ls = longeststr.size(), l0 = ls == 0 ? 0 : longeststr[0].length(), cl = cur.length();
  if (root->num == K) {
    if (ls == 0)
      longeststr.push_back(cur);
    else if (l0 < cl){
      longeststr.clear();
      longeststr.push_back(cur);
    }
    else if(l0 == cl)
      longeststr.push_back(cur);
  }
  for (IT it = root->son.begin(); it != root->son.end(); ++it) {
    string next = cur + it->first;
    if (it->second->num >= K)
      dfs(it->second, K, next, longeststr);
  }  
}
vector<string> isExist(Trie *root, int K) {
  string cur = "";
  vector<string> longeststr;

  dfs(root, K, cur, longeststr);
  return longeststr;
}

int main() {
  Trie* trie = BuildTrie();
  string str[] = {"abc", "ab", "ade", "dcef"};
  for (int i = 0; i < 4; ++i)
	  Insert(trie, str[i]);
  string s = "ab";
  Trie *searchWord = Find(trie, s);
  ListAll(trie, s);		
  vector<string> res = isExist(trie, 1);
  return 0;
}

 

 

 

 

 

 

------------------------------------------------------------------------------

Use array

 

#include <stdio.h>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
const int sonnum=26,base='a';
class Trie
{
 public:
  int num;//to remember how many word can reach here,that is to say,prefix
  bool terminal;//If terminal==true ,the current point has no following point
  Trie *son[sonnum];//the following point
  Trie(bool terminal = true, int num = 0):terminal(terminal), num(num){
    for (int i = 0; i < sonnum; ++i)
      son[i] = NULL;
  }
};
Trie* BuildTrie()// create a new node
{
  Trie *root=new Trie(true, 0);
  root->terminal = false;
  return root;
}
void Insert(Trie* root, string& s)// insert a new word to Trie tree
{
  for(int i=0; i<s.length(); ++i)
  {
    if(root->son[s[i]-base] == NULL)
	    root->son[s[i]-base]=new Trie();
    else 
	    root->son[s[i]-base]->num++;
  	root->terminal = false;
	  root=root->son[s[i]-base];
  }
  root->terminal=true;
}
void Delete(Trie *root)// delete the whole tree
{
  if(root!=NULL)
  {
    for(int i=0;i<sonnum;++i)
	    if(root->son[i]!=NULL)
		    Delete(root->son[i]);
    delete root; 
    root=NULL;
  }
}
Trie* Find(Trie *root,string& s)//trie to find the current word
{
  for(int i=0;i<s.length();++i)
    if(root->son[s[i]-base]!=NULL)
      root=root->son[s[i]-base];
    else 
			return NULL;
  return root;
}
void ListAll(Trie *root,string& cur)
{
  if (root->terminal) {
    cout << cur;
    return;
	}
	else {
	  for (int i = 0; i < sonnum; ++i)
	    if (root->son[i]) {        
	      string tmp = "a";
        tmp[0] += i;
        string next = cur + tmp;
		    ListAll(root->son[i], next);		  
		  }
	}
}
 
int main() {
  Trie* trie = BuildTrie();
  string str[] = {"abc", "ab", "ade", "ace"};
  for (int i = 0; i < 4; ++i)
	  Insert(trie, str[i]);
  string s = "a";
  Trie *searchWord = Find(trie, s);
  ListAll(searchWord, s);		
	
  return 0;
}

The above code is not right:

 

#include <stdio.h>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
const int sonnum=26,base='a';
class Trie
{
 public:
  int num;//to remember how many word can reach here,that is to say,prefix
  bool terminal;//If terminal==true ,the current point has no following point
  Trie *son[sonnum];//the following point
  Trie(bool terminal = false, int num = 1):terminal(terminal), num(num){
    for (int i = 0; i < sonnum; ++i)
      son[i] = NULL;
  }
};
Trie* BuildTrie()// create a new node
{
  Trie *root=new Trie(false, 1);
  return root;
}
void Insert(Trie* root, string& s)// insert a new word to Trie tree
{
  for(int i=0; i<s.length(); ++i)
  {
    if(root->son[s[i]-base] == NULL)
	    root->son[s[i]-base]=new Trie(false,1);
    else 
	    root->son[s[i]-base]->num++;
	  root=root->son[s[i]-base];
  }
  root->terminal=true;
}
void Delete(Trie *root)// delete the whole tree
{
  if(root!=NULL)
  {
    for(int i=0;i<sonnum;++i)
	    if(root->son[i]!=NULL)
		    Delete(root->son[i]);
    delete root; 
    root=NULL;
  }
}
Trie* Find(Trie *root,string& s)//trie to find the current word
{
  for(int i=0;i<s.length();++i)
    if(root->son[s[i]-base]!=NULL)
      root=root->son[s[i]-base];
    else 
			return NULL;
  return root;
}
void ListAll(Trie *root,string& cur)
{
  if (root->terminal)
    cout << cur << endl;
	for (int i = 0; i < sonnum; ++i)
	  if (root->son[i]) {     
	    string tmp = "a";
      tmp[0] += i;
      string next = cur + tmp;
	    ListAll(root->son[i], next);		  
	  }
}
 
int main() {
  Trie* trie = BuildTrie();
  string str[] = {"abc", "ab", "ade", "ace"};
  for (int i = 0; i < 4; ++i)
	  Insert(trie, str[i]);
  string s = "ab";
  Trie *searchWord = Find(trie, s);
  ListAll(searchWord, s);		
	
  return 0;
}

Python Version:

class Node:
    def __init__(self, terminal = False, num = 0):
        self.terminal = False
        self.num = num
        self.son = {}

def BuildTrie():
    root = Node(False, 0)
    return root

def Insert(root, s):
    root.num += 1
    for c in s:
        if (c in root.son):
            root = root.son[c]
            root.num += 1
        else:
            root.son[c] = Node(False, 1)
            root = root.son[c]
    root.terminal = True

def IsExist(root, s):
    for c in s:
        if (c in root.son):
            root = root.son[c]
        else:
            return False
    return root.terminal

if __name__ == '__main__':
    root = BuildTrie()
    for item in ["abc", "ab", "ade", "ace"]:
        Insert(root, item)
    print(IsExist(root, "abc"))
    print(IsExist(root, "abcd"))


 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值