title: Trie树之C++实现

comments: true

date: 2016-10-02 16:59:54

categories: 算法

tags:

  • Trie树

前言

之前写了一篇偏向于理解Trie的文章-Trie树理解

和前面那篇文章不同的是,这一篇文章记录着Trie树的C++实现

介绍

看一下代码的结构

其中:

  • TrieNode : 树的结点,树
  • Client : 客户端(操作树)
  • main : 主函数

Code

TrieNode

TrieNode.hpp

//
// TreeNode.hpp
// Trie
//
// Created by staff on 16/9/29.
// Copyright © 2016年 staff. All rights reserved.
// #ifndef TreeNode_hpp
#define TreeNode_hpp #include <stdio.h>
#include <iostream>
#include <map>
#include <vector>
#include <stack>
using namespace std; #define MAX_CHARS 26 class TreeNode {
public:
TreeNode();
~TreeNode(); void setEnd(bool);
bool getEnd(); void setFreq(int);
int getFreq(); void setNChar(char);
char getNChar(); void setID(int);
int getID(); void setStr(string);
string getStr(); vector<TreeNode *> Childs; private:
bool End;
int Freq;
char NChar;
int Id;
string str;
}; class Tree {
public:
Tree();
~Tree(); void addTrieNode(string word, int id);
void deleteTrieNode();
map<int, string> searchTrie(string word);
void upateTree(string word, int id);
int getWordFreq(string word); private:
TreeNode * root;
void addTrieNode(TreeNode * node, string word, int id);
void deleteTrieNode(TreeNode * root);
map<int, string> searchTrie(TreeNode * root, string word);
int getPrefixCount(TreeNode * root, string word);
void upateTree(TreeNode * root, string word, int id);
int getWordFreq(TreeNode * root, string word);
}; #endif /* TreeNode_hpp */

TreeNode.cpp

//
// TreeNode.cpp
// Trie
//
// Created by staff on 16/9/29.
// Copyright © 2016年 staff. All rights reserved.
// #include "TreeNode.hpp" TreeNode::TreeNode() : End(false), Freq(0), NChar(' '), str("") {
for (int i = 0; i < MAX_CHARS; ++i) {
this->Childs.push_back(nullptr);
}
} TreeNode::~TreeNode() {
for (auto itr = this->Childs.begin(); itr != this->Childs.end(); itr++) {
delete *itr;
*itr = nullptr;
}
this->Childs.clear();
} void TreeNode::setEnd(bool value) {
this->End = value;
} bool TreeNode::getEnd() {
return this->End;
} void TreeNode::setFreq(int value) {
this->Freq = value;
} int TreeNode::getFreq() {
return this->Freq;
} void TreeNode::setNChar(char value) {
this->NChar = value;
} char TreeNode::getNChar() {
return this->NChar;
} void TreeNode::setID(int value) {
this->Id = value;
} int TreeNode::getID() {
return this->Id;
} void TreeNode::setStr(string value) {
this->str = value;
} string TreeNode::getStr() {
return this->str;
} Tree::Tree() {
this->root = new TreeNode();
} Tree::~Tree() { } void Tree::addTrieNode(TreeNode * root, string word, int id) {
if (word.size() == 0) {
return ;
} TreeNode * pNode = root;
for (int i = 0; i < word.size(); ++i) {
int idx = word[i] - 'a';
if (pNode->Childs[idx] == nullptr) {
pNode->Childs[idx] = new TreeNode();
}
pNode->Childs[idx]->setNChar(word[i]);
pNode->Childs[idx]->setStr(pNode->getStr() + pNode->Childs[idx]->getNChar());
pNode = pNode->Childs[idx];
} pNode->setID(id);
pNode->setFreq(pNode->getFreq()+1);
pNode->setEnd(true);
} void Tree::deleteTrieNode(TreeNode * root) {
TreeNode * node = root;
for (int i = 0; i < MAX_CHARS; ++i) {
if (node->Childs[i]) {
deleteTrieNode(node->Childs[i]);
}
} delete(node);
node = nullptr;
} map<int, string> Tree::searchTrie(TreeNode * root, string word) {
if (word.size() == 0) {
return {};
} map<int, string> result;
TreeNode * pNode = root;
int i = 0; for (; i < word.size(); ++i) {
int idx = word[i] - 'a'; if (pNode->Childs[idx] == nullptr) {
break;
} pNode = pNode->Childs[idx];
} if (i != word.size()) {
cout << "not exist!" << endl;
return {};
}
else {
result.insert(make_pair(pNode->getID(), pNode->getStr()));
stack<TreeNode *> stack;
stack.push(pNode); while (!stack.empty()) {
TreeNode * node = stack.top();
stack.pop(); for (int j = 0; j < MAX_CHARS; ++j) {
if (node->Childs[j]) {
if (node->Childs[j]->getEnd()) {
result.insert(make_pair(node->Childs[j]->getID(), node->Childs[j]->getStr()));
}
else {
stack.push(node->Childs[j]);
}
}
}
}
return result;
} } /**
* 词频统计,出现字符串的个数
*
* @param root <#root description#>
* @param word <#word description#>
*
* @return <#return value description#>
*/
int Tree::getWordFreq(TreeNode * root, string word) {
TreeNode * pNode = root; int i = 0;
for (; i < word.size(); ++i) {
int idx = word[i] - 'a'; if (pNode->Childs[idx] == nullptr) {
return 0;
} pNode = pNode->Childs[idx];
} return pNode->getFreq();
} void Tree::upateTree(TreeNode * root, string word, int id) {
deleteTrieNode(root);
addTrieNode(root, word, id);
} void Tree::addTrieNode(string word, int id) {
this->addTrieNode(this->root, word, id);
} void Tree::deleteTrieNode() {
this->deleteTrieNode(this->root);
} map<int, string> Tree::searchTrie(string word) {
return this->searchTrie(root, word);
} int Tree::getWordFreq(string word) {
return this->getWordFreq(this->root, word);
} void Tree::upateTree(string word, int id) {
this->upateTree(this->root, word, id);
}

Client

Client.hpp

//
// Client.hpp
// Trie
//
// Created by staff on 16/9/29.
// Copyright © 2016年 staff. All rights reserved.
// #ifndef Client_hpp
#define Client_hpp #include <stdio.h>
#include <iomanip>
#include <fstream>
#include <string>
#include <algorithm>
#include <map>
#include "TreeNode.hpp"
using namespace std; class Client {
public:
Client();
~Client();
void test(); private:
Tree *tree;
}; #endif /* Client_hpp */

Client.cpp

//
// Client.cpp
// Trie
//
// Created by staff on 16/9/29.
// Copyright © 2016年 staff. All rights reserved.
// #include "Client.hpp" Client::Client() {
this->tree = new Tree();
} Client::~Client() { } void Client::test() { ifstream infile;
infile.open("/Users/George/Desktop/out.txt");
string message;
char buf[1024]; if (infile.is_open()) {
while (infile.good() && !infile.eof()) {
memset(buf, 0, 1024);
infile.getline(buf, 1024);
message = buf; size_t size = message.length();
size_t space = message.find_first_of(' '); int id = atoi(message.substr(0, space).c_str());
string word = message.substr(space+1, size-1);
word.erase(word.end()-1); transform(word.begin(), word.end(), word.begin(), ::tolower); this->tree->addTrieNode(word, id);
} char input[20];
printf("please input\n");
scanf("%s", input); int content_count = this->tree->getWordFreq(input);
printf("content count : %d\n", content_count); map<int, string> ids = this->tree->searchTrie(input); int prefix_count = (int)ids.size();
printf("prefix count : %d\n\n", prefix_count); for (auto id : ids) {
printf("%d:%s\n", id.first, id.second.c_str());
} }
else {
printf("无法读取文件\n");
} infile.close();
}

main

//
// main.cpp
// Trie
//
// Created by staff on 16/9/28.
// Copyright © 2016年 staff. All rights reserved.
// #include <stdio.h>
#include "Client.hpp" int main(int argc, const char * argv[]) {
// insert code here...
Client * client = new Client();
client->test(); return 0;
}

结果

Trie树之C-实现的更多相关文章

  1. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  2. 基于trie树的具有联想功能的文本编辑器

    之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...

  3. hihocoder-1014 Trie树

    hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...

  4. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

  5. 通过trie树实现单词自动补全

    /** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...

  6. #1014 Trie树

    本题主要是求构造一棵Trie树,即词典树用于统计单词. C#代码如下: using System; using System.Collections.Generic; using System.Lin ...

  7. Trie树-字典查找

    描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...

  8. Trie树的创建、插入、查询的实现

    原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947 1.什么是Trie树 Tr ...

  9. Trie树(c++实现)

    转:http://www.cnblogs.com/kaituorensheng/p/3602155.html http://blog.csdn.net/insistgogo/article/detai ...

  10. [转]双数组TRIE树原理

    原文名称: An Efficient Digital Search Algorithm by Using a Double-Array Structure 作者: JUN-ICHI AOE 译文: 使 ...

随机推荐

  1. 洛谷 P4559: bzoj 5319: [JSOI2018]军训列队

    题目传送门:洛谷 P4559. 题意简述: 有 \(n\) 个学生,编号为 \(i\) 的学生有一个位置 \(a_i\). 有 \(m\) 个询问,每次询问编号在 \([l,r]\) 区间内的学生跑到 ...

  2. APUE-文件和目录(二)函数access,mask,chmod和粘着位

    4.7 函数access和faccessat 当一个进程使用了设置用户ID和设置组ID作为另一个用户(或者组)运行时,这时候有效用户(组)ID和实际用户(组)ID不一样,但进程仍然希望测试实际用户(组 ...

  3. 003_ElasticSearch详解与优化设计

    简介 概念 安装部署 ES安装 数据索引 索引优化 内存优化 1简介 ElasticSearch(简称ES)是一个分布式.Restful的搜索及分析服务器,设计用于分布式计算:能够达到实时搜索,稳定, ...

  4. Access中替代case when的方法 .

    最近在做一个用Access的东东,其中用到了case when的方式,但是Access是不支持这种语法的,查询知道IIf和Swith可以作为替代,总结如下: IIf(expr, truepart, f ...

  5. Ubuntu下使用virtualenv

    Ubuntu 18.04,Python 3.6.5(最新3.7),virtualenv 16.0.0, 即将在Ubuntu上大张旗鼓地干活啦!那么,将之前安装的virtualenv运行起来吧(前面都是 ...

  6. ipad webapp禁止长按选择

    1.禁止长按屏幕弹出对话框并选中文字 /*禁止长按选择文字事件*/ * { -webkit-touch-callout: none; -webkit-user-select: none; -khtml ...

  7. Code Conventions for the JavaScript Programming Language

    This is a set of coding conventions and rules for use in JavaScript programming. It is inspired by t ...

  8. 为通过 ATS 检测 Tomcat 完全 TLS v1.2、完全正向加密及其结果检验

    2017 年起 app store 要求 app 对接的服务器支持 TLS v1.2,否则 ats 检测不予通过.有点强制推 TLS v1.2 的意味.本文介绍如何使 tomcat 强制执行 TLS ...

  9. grail开发环境的搭建

    本文参考:Grails入门指南(第二版) 1. 下载jdk和Grail http://www.oracle.com/technetwork/java/javase/downloads/ http:// ...

  10. 使用Oracle数据库,对某个表频繁更新

    使用Oracle数据库,对某个表频繁更新,查询时要联合这张表,查询速度非常慢,有什么解决办法? 一般的pc机oracle更新的效率均可达到500+/s, 可能的问题,你更新这个不会是每次都新建jdbc ...