后缀树

原创 2016年08月29日 21:12:46
<span style="font-size:18px;">后缀树--包含字符串所有后缀的压缩的字典树,<span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">给定一长度为n的字符串S=S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">1</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">2</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">..S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">i</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">..S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">n</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">,和整数i,1 <= i <= n,子串S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">i</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">i+1</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">...S</span><sub style="font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; padding: 0px;">n</sub><span style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">都是字符串S的后缀。以字符串S=XMADAMYX为例,它的长度为8,所以S[1..8], S[2..8], ... , S[8..8]都算S的后缀,我们一般还把空字串也算成后缀。这样,我们一共有如下后缀。对于后缀S[i..n],我们说这项后缀起始于i。</span></span><ol style="margin: 0px; padding: 0px 0px 0px 40px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);"><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[1..8], XMADAMYX, 也就是字符串本身,起始位置为1</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[2..8], MADAMYX,起始位置为2</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[3..8], ADAMYX,起始位置为3</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[4..8], DAMYX,起始位置为4</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[5..8], AMYX,起始位置为5</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[6..8], MYX,起始位置为6</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[7..8], YX,起始位置为7</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">S[8..8], X,起始位置为8</li><li style="margin: 0px 0px 1em; padding: 0px; list-style: decimal;">空字串。记为$。</li></ol>
<span style="font-size:18px;">后缀树的应用</span>
<span style="font-size:18px;">后缀树的应用包括:查询主串是否包含子串,找出两字符串的最长公共子串,找出主串的最长回文字串,找出主串中的最长重复子串等等</span>
// ConsoleApplication17.cpp : 定义控制台应用程序的入口点。
//后缀数组--用于匹配子串

#include "stdafx.h"
#include<string>
#include<iostream>
#include<map>
#include<vector>
using namespace std;
struct SuffixTreeNode{
	map<char, SuffixTreeNode*> children;
	char value;
	vector<int> indexes;//
	void InsertString(string s1, int index){
		
		if (s1.length() > 0){
			char s = s1[0];
			SuffixTreeNode *child = NULL;
			if (children.find(s) != children.end()){
				child = children[s];
			}
			else{
			     SuffixTreeNode* newNode=new SuffixTreeNode;
				 child = newNode;
				 child->value = s;
				 children[s] = child;
				 
			}
			string remain = s1.substr(1);
			child->indexes.push_back(index);
			child->InsertString(remain, index);
		}
	
	}
	vector<int> Get_index(string s1){
		char s = s1[0];
		if (s1.length() == 0)
			return indexes;
		else{
			if (children.find(s) != children.end()){
				string str = s1.substr(1);
				SuffixTreeNode *child = children[s];
				return child->Get_index(str);
			}
			else{
				vector<int> empty;
				return empty;
			}
		}
	}
	~SuffixTreeNode(){
		map<char, SuffixTreeNode*>::iterator iter;
		for (iter = children.begin(); iter != children.end(); iter++){
			delete iter->second;
		}
	}

};
class SuffixTree{
public:
	SuffixTreeNode* root;
	SuffixTree(string s){
		root = new SuffixTreeNode;
		for (int i = 0; i < s.length(); i++){
			string str = s.substr(i);
			root->InsertString(str, i);
		}
	};
	vector<int> getindex(string s){
		return root->Get_index(s);

	}
	~SuffixTree(){
		if (root != NULL){
			delete root;
		}
	}
	void printSuffixTree(SuffixTreeNode* root){
		if (root)
		{
			cout << root->value << " ";
			map<char, SuffixTreeNode*>::iterator iter;
			for (iter = root->children.begin(); iter != root->children.end(); iter++){
				//cout << endl;
				printSuffixTree((iter)->second);
			}
            

			}
		}
	};
	int _tmain(int argc, _TCHAR* argv[])
	{
		string testString = "mississippi";
		string stringList[] = { "is", "sip", "hi", "sis" };
		SuffixTree stree(testString);
		stree.printSuffixTree(stree.root);
		for (int i = 0; i < 4; i++){
			vector<int> li = stree.getindex(stringList[i]);
			if (li.size() != 0){
			cout << stringList[i].c_str() << " ";
			for (int j = 0; j < li.size(); j++){
			cout << li[j] << " ";
			}
			cout << endl;

			}

			}
		system("pause");
		return 0;
	}
<img src="http://img.blog.csdn.net/20160830150232203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

版权声明:本文为博主原创文章,未经博主允许不得转载。

数据结构系列——后缀树(附Java实现代码)

后缀树,说的通俗点就是将一个字符串所有的后缀按照前缀树(Trie树,可参考此篇文章)的形式组织成一棵树。本文章介绍了后缀树的应用以及使用如何使用Java实现Ukkonen算法构建后缀树...
  • hqshaozhu
  • hqshaozhu
  • 2015年11月27日 13:34
  • 2260

搜索引擎中长串匹配及聚类算法:后缀树算法(Java版)

前两天用C++写了一个后缀树算法,今天把它直译成java了,经过一晚上的努力终于调试通了,现在把构造后缀树的核心代码贴出来,大家可以交流一下,比如查找下一个更短的后缀时有木有更好的方法啊. 然后在测...
  • Aiphis
  • Aiphis
  • 2015年09月18日 09:14
  • 692

[算法系列之二十五]Ukkonen后缀树算法

所以我们从左边开始,第一次只插入单字符”a”,通过创建一个从根节点到一个叶节点的边(根节点左边),并且标记这条边[0,#],意思是说这条边代表了从0开始到当前末尾的子串。我使用#来表示当前末尾,当前末...
  • SunnyYoona
  • SunnyYoona
  • 2015年02月28日 15:30
  • 2317

使用后缀树快速处理字符串匹配

说明:标注有“飞说不可”的话就是俺说的了,鉴于本人英语水平和学习能力有限,有什么不对的地方敬请拍砖。如果有什么理解错误或者没有表述清楚的地方,请一定要跟我联系啊。在此多谢了。中文如果有版权就是俺fei...
  • feixeyes
  • feixeyes
  • 2012年03月15日 16:40
  • 3916

后缀树系列一:概念以及实现原理( the Ukkonen algorithm)

首先说明一下后缀树系列一共会有三篇文章,本文先介绍基本概念以及如何线性时间内构件后缀树,第二篇文章会详细介绍怎么实现后缀树(包含实现代码),第三篇会着重谈一谈后缀树的应用。   本文分为三...
  • zzuchengming
  • zzuchengming
  • 2016年03月20日 11:09
  • 849

算法学习:后缀自动机转后缀树转后缀数组

算法学习:后缀自动机转后缀树转后缀数组 引入 其实这是一篇水文 想要学后缀自动机的话去查2012年noi冬令营陈立杰讲稿 顺便说一句,讲稿上有一些错误,多翻几篇博客加深理解。 今天这里主...
  • lvzelong2014
  • lvzelong2014
  • 2018年01月08日 20:36
  • 98

后缀树总结+详细解释的代码

几年前曾实现过一个菜鸟版的SuffixTree。最近要用到后缀树处理些问题,认真实现了一个,主要是基于UKKonen的On-Line算法。稍微总结下。   网上关于后缀树介绍的文章有几篇写的挺好的,...
  • qiul12345
  • qiul12345
  • 2012年09月22日 20:40
  • 1910

后缀树简单整理-上

定义后缀树(Suffix tree)是一种数据结构,能快速解决很多关于字符串的问题。后缀树的概念最早由Weiner 于1973年提出,既而由McCreight 在1976年和Ukkonen在1992年...
  • baidu_21040027
  • baidu_21040027
  • 2016年11月04日 11:12
  • 167

前缀树和后缀树

今天主要看的是树中的两个比较重要的数据结构——前缀树和后缀树。在此之前,先来看两个问题。(参考博客:从Trie树(字典树)谈到后缀树)...
  • u013949069
  • u013949069
  • 2017年09月21日 19:49
  • 307

后缀自动机与线性构造后缀树

LINK: http://fanhq666.blog.163.com/blog/static/8194342620123352232937/ 冬令营上我犯了最大的一个错误,就是在陈立杰讲后缀...
  • Aiphis
  • Aiphis
  • 2015年10月28日 06:44
  • 557
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:后缀树
举报原因:
原因补充:

(最多只允许输入30个字)