Trie树之C-实现
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-实现的更多相关文章
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- hihocoder-1014 Trie树
hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...
- 洛谷P2412 查单词 [trie树 RMQ]
题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...
- 通过trie树实现单词自动补全
/** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...
- #1014 Trie树
本题主要是求构造一棵Trie树,即词典树用于统计单词. C#代码如下: using System; using System.Collections.Generic; using System.Lin ...
- Trie树-字典查找
描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...
- Trie树的创建、插入、查询的实现
原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947 1.什么是Trie树 Tr ...
- Trie树(c++实现)
转:http://www.cnblogs.com/kaituorensheng/p/3602155.html http://blog.csdn.net/insistgogo/article/detai ...
- [转]双数组TRIE树原理
原文名称: An Efficient Digital Search Algorithm by Using a Double-Array Structure 作者: JUN-ICHI AOE 译文: 使 ...
随机推荐
- C# 托管资源 与 非托管资源
C# 托管资源 与 非托管资源 托管资源一般是指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,.NET可以自动进行回收,主要是指托管堆上分配的内存资源.例如程序中分配的对象,作用域内的变量 ...
- acm专题---KMP模板
KMP的子串长n,模式串长m,复杂度o(m+n),朴素做法的复杂度o((n-m+1)*m) 觉得大话数据结果上面这个讲得特别好 改进版本的KMP leetcode 28. Implement strS ...
- java基础62 JavaScript中的函数(网页知识)
1.JavaScript中,函数的格式 function 函数名(形参列表){ 函数体; } 2.JavaScript中,函数需要注意的细节 1.在javaScript中,函数定义形参时,是不能使用v ...
- 夜神模拟器调试android studio项目
这几天为了android studio也是醉了,先是R文件丢失忙活一下午,各种百度谷歌,最后终于解决这个小问题,没想到在启动avd这个问题上更是棘手,网上的方法试了,主要有三种,上篇博文http:// ...
- sqlserver sp_spaceused用法
sp_spaceused显示行数.保留的磁盘空间以及当前数据库中的表所使用的磁盘空间,或显示由整个数据库保留和使用的磁盘空间. 语法sp_spaceused [[@objname =] 'objnam ...
- java通过POI和easypoi实现Excel的导出
前言 在工作经常会遇到excel导出报表的功能,自己也做过一些,然后在项目里看到同事封装的一个excel导出工具类,着实不错,拿来分享一下.然后,又在网上看到一个使用easypoi实现cxcel导出的 ...
- Mongodb配置:error:10061 由于目标计算机积极拒绝,无法连接
相信很多学Node的同学,在进入MongoDB后台管理 Shell的时候都会“遇到error:10061 由于目标计算机积极拒绝,无法连接”这种情况,很多情况都是dbpath与dblog的路径没有配置 ...
- Hive(六)内置函数与高级操作
一内置函数 1 数学函数 Return Type Name (Signature) Description DOUBLE round(DOUBLE a) Returns the rounded BIG ...
- day1作业二:多级菜单操作
作业二:多级菜单 (1)三级菜单 (2)可以次选择进入各子菜单 (3)所需新知识点:列表.字典 要求:输入back返回上一层,输入quit退出整个程序 思路: (1)首先定义好三级菜单字典: (2)提 ...
- jquery图片延迟加载方案解决图片太多加载缓慢问题
当在做一个图片展示站的时候,一个页面加载的图片过多会,如果服务器的带宽跟不上,明显会感觉到页面很卡,严重的浏览器也会崩溃,所以我推荐采用即看即所得的模式,当滚动到下一屏时才进行加载图片. 注意:即便如 ...