字符串前缀、后缀、子串、字典树
Trie(字典树,前缀树)_模板
![Trie(字典树,前缀树)_模板](https://img.taocdn.com/s3/m/ed246acb6e1aff00bed5b9f3f90f76c661374c17.png)
Trie(字典树,前缀树)_模板TrieTrie,⼜经常叫前缀树,字典树等等。
Trie,⼜称前缀树或字典树,⽤于保存关联数组,其中的键通常是字符串。
与⼆叉查找树不同,键不是直接保存在节点中,⽽是由节点在树中的位置决定。
⼀个节点的所有⼦孙都有相同的前缀,也就是这个节点对应的字符串,⽽根节点对应空字符串。
⼀般情况下,根节点不保存值,这样可以把⼏个开头不同的串连在⼀颗Trie上(如abc,efg)。
Trie中的键通常是字符串(所以常叫字典树)。
优点可以最⼤限度地减少⽆谓的字符串⽐较,故可以⽤于词频统计和⼤量字符串排序。
缺点虽然不同单词共享前缀,但其实trie是⼀个以空间换时间的算法。
其每⼀个字符都可能包含⾄多字符集⼤⼩数⽬的指针。
建树两种建法:(1) 多叉树:仅字母:26或52,各种字母,数字,符号组合:根据情况算吧,反正需要的空间贼⼤(2) 兄弟⼉⼦表⽰法:⽤链表,如链式前向星(个⼈⽐较喜欢),遍历时间较上⼀种长应⽤(1)字符串检索(2)⽤多叉树建的树可以实现字典序排序(3)最长公共前缀(4)AC⾃动机等会⽤到促使我学习Trie的题⽬:UVA 11732 "strcmp()" Anyone?并没有UVA,其他OJ⼤概也搜得到这道题给出⼀个 strcmp() 函数的实现⽅式,我们要求的就是判断 ‘==’ 的次数int strcmp(char *s, char *t){int i;for (i = 0; s[i] == t[i]; i++)if (s[i] == 0) return0;return s[i] - t[i];}题⾯由于要⽐较最后的 0,那么字符串相等则答案加 2 * strlen(str) + 2,否则加 2 * ptr + 1,ptr为中断位置。
代码我使⽤的是兄弟⼉⼦表⽰法(很显然),时间复杂度的话,不是很慢,还⾏吧 . . .1 #include<cstdio>2 #include<cstring>3 #include<iostream>4#define CL(X,N) memset((X), (N), sizeof(X))5using namespace std;6 typedef long long LL;7const int maxl = 1e3 + 10, maxn = 4e3 + 10;8int n;9char str[maxl];10int son[maxn * maxl], bro[maxn * maxl], cnt[maxn * maxl];11char trie[maxn * maxl];12 LL size = 0, ans = 0;1314 inline void Insert(char *s, int len) {15int ptr, cur = 0;16for(int i = 0; i <= len; ++i) {17for(ptr = son[cur]; ptr; ptr = bro[ptr])18if(trie[ptr] == s[i]) break;19if(!ptr) {20 ptr = size++;21 trie[ptr] = s[i];22 bro[ptr] = son[cur];23 son[cur] = ptr;24 cnt[ptr] = 0;25 son[ptr] = 0;26 }27 ans += (cnt[cur] - cnt[ptr]) * (2 * i + 1);28if(i == len) {29 ans += cnt[ptr] * (2 * i + 2);30 ++cnt[ptr];31 }32 ++cnt[cur];33 cur = ptr;34 }35return ;36 }3738 inline void Initialize(void) {39 son[0] = bro[0] = cnt[0] = 0;40 ans = 0;41 size = 1;42return ;43 }4445int main(int argc, char **argv) {46 #ifdef LOCAL47 freopen("in.txt", "r", stdin);48#endif49int len, cas = 0;50while(~scanf("%d", &n) && n) {51 Initialize();52for(int i = 0; i < n; ++i) {53 scanf("%s", str);54 len = strlen(str);55 Insert(str, len);56 }57 printf("Case %d: %lld", ++cas, ans);58 putchar(10);59 }60return0;61 }View Code。
前缀树与后缀树高效处理字符串匹配问题的数据结构
![前缀树与后缀树高效处理字符串匹配问题的数据结构](https://img.taocdn.com/s3/m/24b0b2b37d1cfad6195f312b3169a4517723e5cc.png)
前缀树与后缀树高效处理字符串匹配问题的数据结构字符串匹配问题是计算机科学领域中的重要研究方向之一。
在许多应用中,我们需要快速有效地判断一个字符串是否出现在另一个长字符串中,或者找到所有出现的位置。
为了解决这个问题,计算机科学家们提出了许多数据结构和算法,其中前缀树和后缀树被广泛用于高效处理字符串匹配问题。
一、前缀树前缀树,也称为Trie树或字典树,是一种特殊的多叉树结构,用于存储和检索字符串数据集。
它的特点是每个节点表示一个字符,从根节点到叶子节点的路径组成的字符串即为该节点所代表的字符串。
通过构建前缀树,我们可以快速查找某个字符串是否存在,以及找到以某个字符串为前缀的所有字符串。
在构建前缀树时,我们从根节点开始,逐个字符插入。
如果当前字符已经存在于当前节点的子节点中,则继续向下遍历;否则,我们创建一个新的节点并将其插入到当前节点的子节点中。
通过这种方式,我们可以在O(m)的时间复杂度内插入一个长度为m的字符串。
在搜索字符串时,我们从根节点开始,逐个字符匹配。
如果当前字符存在于当前节点的子节点中,则继续向下匹配;如果不存在,则结束搜索。
如果搜索过程中遇到叶子节点,表示匹配成功,可以返回结果。
通过这种方式,我们可以在O(m)的时间复杂度内完成字符串的查找。
二、后缀树后缀树是一种特殊的前缀树,用于高效处理字符串匹配问题。
与前缀树不同,后缀树存储的是原始字符串的所有后缀。
通过构建后缀树,我们可以快速查找某个字符串是否是原始字符串的子串,并找到所有出现的位置。
构建后缀树的过程相对复杂一些。
首先,我们需要将原始字符串的所有后缀插入到后缀树中。
为了避免生成冗余节点,我们可以使用路径压缩的方式,在插入过程中合并相同前缀的节点。
通过这种方式,我们可以在O(n)的时间复杂度内构建后缀树,其中n为原始字符串的长度。
在搜索字符串时,我们从根节点开始,逐个字符匹配。
如果当前字符存在于当前节点的子节点中,则继续向下匹配;如果不存在,则结束搜索。
字典树(前缀树)的实现
![字典树(前缀树)的实现](https://img.taocdn.com/s3/m/b7dc574c326c1eb91a37f111f18583d049640fef.png)
字典树(前缀树)的实现在实现字典树(前缀树)之前,我们先看⼀下什么是字典树(前缀树)“字典树⼜称前缀树,Trie树,是⼀种树形结构,是⼀种哈希树的变种。
典型应⽤是⽤于统计,排序和保存⼤量的字符串(但不仅限于字符串),所以经常被搜索引擎系统⽤于⽂本词频统计。
它的优点是:利⽤字符串的公共前缀来减少查询时间,最⼤限度地减少⽆谓的字符串⽐较,查询效率⽐哈希树⾼。
”------百度百科字典树是⼀种树形结构,优点是利⽤字符串的公共前缀来节约存储空间。
字典树如图1所⽰:图1在字典树上搜索添加过的单词的步骤如下:1、从根结点开始搜索2、取得要查找单词的第⼀个字母,并根据该字母选择对应的字符路径向下继续搜索。
3、字符路径指向的第⼆层节点上,根据第⼆个字母选择对应的字符路径向下继续搜索。
4、⼀直向下搜索,如果单词搜索完后,找到的最后⼀个节点是⼀个终⽌节点,⽐如图1中的实⼼节点,说明字典树中含有这个单词,如果找到的最后⼀个节点不是⼀个终⽌节点,说明单词不是字典树中添加过的单词。
如果单词没搜索完,但是已经没有后续的节点了,也说明单词不是字典树中添加过的单词。
题⽬:字典树(前缀树)的实现:字典树⼜称为前缀树或Trie树,是处理字符串常见的数据结构。
假设组成所有单词的字符串是“a”~“z”,请实现字典树结构,并包含以下四个主要功能。
void insert(String word):添加word,可以重复添加。
void delete(String word):删除word,如果word添加过多次,仅删除⼀个。
boolean search(String word):查询word是否在字典树中。
int prefixNumber(String pre):返回以字符串pre为前缀的单词数量。
1class TrieNode {2int path;3int end;4 TrieNode[] map;56 TrieNode() {7 path=0;8 end=0;9 map=new TrieNode[26];10 }11 }12class Trie {13private TrieNode root;14public Trie() {15 root=new TrieNode();16 }17public void insert(String word) {18if (word==null) {19return;20 }21char[] chs=word.toCharArray();22 TrieNode node=root;23 node.path++;24int index=0;25for (int i=0; i<chs.length; i++) {26 index=chs[i]-'a';27if (node.map[index]==null) {28 node.map[index]=new TrieNode();29 }30 node=node.map[index];31 node.path++;32 }33 node.end++;34 }35public void delete(String word) {36if (search(word)) {37char[] chs=word.toCharArray();38 TrieNode node=root;39 node.path--;40int index=0;41for (int i=0; i<chs.length; i++) {42 index=chs[i]-'a';43 node.map[index].path--;44 node=node.map[index];45 }46 node.end--;47 }48 }49public boolean search(String word) {50if (word==null) {51return false;52 }53char[] chs=word.toCharArray();54 TrieNode node=root;55int index=0;56for (int i=0; i<chs.length; i++) {57 index=chs[i]-'a';58if (node.map[index]==null) {59return false;60 }61 node=node.map[index];62 }63return node.end!=0;64 }65public int prefixNumber(String pre) {66if (pre==null) {67return 0;68 }69char[] chs=pre.toCharArray();70 TrieNode node=root;71int index=0;72for (int i=0; i<chs.length; i++) {73 index=chs[i]-'a';74if (node.map[index]==null) {75return 0;76 }77 node=node.map[index];78 }79return node.path;80 }81 }LeetCode208实现Trie(前缀树)题⽬描述:实现⼀个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
前缀树与后缀树了解前缀树和后缀树的应用与实现
![前缀树与后缀树了解前缀树和后缀树的应用与实现](https://img.taocdn.com/s3/m/611d013f1611cc7931b765ce0508763231127400.png)
前缀树与后缀树了解前缀树和后缀树的应用与实现前缀树与后缀树:了解前缀树和后缀树的应用与实现在计算机科学领域中,有两种重要的数据结构,即前缀树(Trie树)和后缀树,它们被广泛应用于字符串处理、搜索引擎和自然语言处理等领域。
本文将介绍前缀树和后缀树的定义、应用以及实现方式。
一、前缀树前缀树,又称为Trie树,是一种特殊的多叉树,用于存储和快速检索字符串数据集。
前缀树的每个节点代表一个字符,从根节点到叶节点的路径构成一个完整的字符串。
每个节点包含指向子节点的指针,并用于在树中快速确定特定字符串的存在。
前缀树的一个主要应用是前缀匹配,即根据前缀快速查找以该前缀开头的所有字符串。
这在自动补全、拼写检查和搜索引擎的关键字建议中起着重要作用。
前缀树的实现可以使用数组、链表或哈希表等不同的数据结构,根据实际情况选择最适合的方式。
二、后缀树后缀树是一种特殊的树型数据结构,用于处理字符串集合中的后缀匹配问题。
与前缀树不同的是,后缀树是输入字符串的后缀的一种压缩表示方式。
通过构建后缀树,可以快速地确定一个字符串在字符串集合中的出现次数、最长公共子串等信息。
后缀树的应用非常广泛,比如字符串匹配、模式搜索和基因组序列分析等。
其高效的存储和查询性能使得后缀树成为处理大规模文本的理想解决方案。
后缀树的构建算法较为复杂,主要有朴素算法和Ukkonen算法等。
通过合理选择算法和数据结构,可以在合理的时间和空间复杂度内构建高效的后缀树。
三、前缀树与后缀树的应用与实现1. 字符串搜索与匹配:前缀树和后缀树可以用于快速确定一个字符串是否存在于给定的字符串集合中,并且可以高效地进行模式匹配和搜索操作。
2. 自动补全和拼写检查:通过构建前缀树,可以实现自动补全和拼写纠错功能,提升用户体验。
例如,当用户输入部分关键字时,前缀树可以快速返回与该前缀相关的所有可能的完整词语。
3. 文本处理和搜索引擎:后缀树在搜索引擎中扮演着重要角色,能够快速检索出包含特定关键字的文档。
trie字典树总结 -回复
![trie字典树总结 -回复](https://img.taocdn.com/s3/m/7f2541812dc58bd63186bceb19e8b8f67c1cefc0.png)
trie字典树总结-回复什么是trie字典树?Trie字典树,也称为前缀树,是一种特殊的树形数据结构,用于存储和检索键-值对。
它的特点是使用字符串中的字符作为节点进行构建,键的相同前缀被合并为一个子树,从而实现快速的字符串检索。
trie字典树是一种高效的数据结构,特别适用于处理大量字符串的场景,如搜索引擎、计算机网络和编译器等。
trie字典树的特点是什么?1. 前缀共享:trie字典树能够有效地利用字符串键的前缀共享。
例如,假设要存储"apple"、"app"和"application"这三个键,它们的前缀"app"会在trie中被合并为一个子树,从而节省了空间。
2. 快速查找:利用trie字典树,我们可以在O(m)的时间复杂度下(其中m是键的长度)查找到指定的字符串。
trie字典树将键分布在树中,每个字符都是树的一个节点,通过将输入字符串的字符一个一个地与树的节点进行匹配,最终找到完整的键。
3. 空间效率:尽管trie字典树可能需要较多的内存来存储节点,但它可以大大减少存储重复前缀带来的额外开销。
对于字符串数量较多或重复前缀较长的数据集,trie字典树可以更好地利用内存空间。
trie字典树的基本结构是什么?trie字典树由多个节点组成,每个节点包含一个字符和若干指向子节点的指针。
通常,根节点不包含字符,其他节点分别表示某个字符。
每个节点还存储一个布尔值,表示当前节点是否为某个字符串的结尾。
trie字典树的节点可能有多个子节点,取决于输入字符串的不同字符数。
对于小写英文字母,一个节点最多有26个子节点。
这种结构使得trie字典树可以有效地处理大量的字符串。
trie字典树的构建过程是怎样的?1. 创建根节点:首先,我们需要创建一棵空的trie字典树,只包含一个根节点。
根节点不包含字符,即为空。
2. 插入键值对:对于要插入的每个键值对,我们从根节点开始,按照键中的字符顺序依次遍历trie树。
前缀树与后缀树处理字符串匹配和检索的高效结构
![前缀树与后缀树处理字符串匹配和检索的高效结构](https://img.taocdn.com/s3/m/8c20d6d66aec0975f46527d3240c844769eaa0f7.png)
前缀树与后缀树处理字符串匹配和检索的高效结构前缀树和后缀树是计算机科学中一种高效处理字符串匹配和检索的数据结构。
它们通过将字符串存储在树形结构中,以便在大规模数据集中快速找到匹配的字符串或者进行模糊匹配。
一、前缀树前缀树(Trie树)是一种树形结构,用于存储字符串集合。
它的核心思想是利用共同的前缀来压缩存储空间,并提供高效的字符串匹配操作。
前缀树由根节点和一系列表示字符的子节点组成。
每个节点可以包含多个子节点,每个子节点对应一个字符。
每一条从根节点到叶子节点的路径表示一个完整的字符串。
前缀树的构建过程是逐个插入字符串的字符。
例如,将字符串"apple"插入前缀树中时,根节点的子节点中会有一个代表字符"a"的子节点,而该子节点的子节点中又会有一个代表字符"p"的子节点,以此类推。
最终,字符串"apple"的所有字符都会被插入到前缀树中。
使用前缀树进行字符串匹配时,可以通过从根节点开始逐个匹配字符的方式快速找到匹配的字符串。
例如,当需要查找前缀为"app"的所有字符串时,只需从根节点开始,按照"a"->"p"->"p"的顺序找到对应的子节点即可。
二、后缀树后缀树是前缀树的一种特殊形式,用于处理字符串的后缀匹配和模糊匹配。
它的构建过程与前缀树类似,不同之处在于后缀树存储的是字符串的所有后缀。
后缀树的构建过程是逐个插入字符串的后缀。
例如,对于字符串"apple",其后缀为"apple"、"pple"、"ple"、"le"和"e"。
将这些后缀按照顺序插入后缀树中,就可以构建出完整的后缀树。
后缀树的一个重要应用是实现快速的字符串模糊匹配操作。
字典树trie详解
![字典树trie详解](https://img.taocdn.com/s3/m/a7a13c632e60ddccda38376baf1ffc4fff47e261.png)
字典树trie详解字典树(Trie),也叫前缀树或字符树,是一种特殊的多叉树结构。
它的主要应用是用于字符串的存储和快速检索。
字典树的核心思想是利用字符串的公共前缀来节省存储空间和提高查询效率。
字典树的结构非常简单,它由根节点和若干个子节点组成。
每个节点表示一个字符,节点之间通过边相连,边上标记着字符的值。
根节点不包含字符值,每个子节点表示一个字符值。
除了根节点外,每个节点还包含一个布尔变量,用来标记该节点是否为某个字符串的结束节点。
通过这种方式,字典树可以高效地存储大量的字符串。
在字典树中,从根节点到任意一个节点的路径表示一个字符串。
通过不断地向下遍历节点,可以得到该字符串的所有前缀。
因此,字典树的查询操作非常高效,时间复杂度为O(k),其中k是待查询字符串的长度。
字典树的构建过程非常简单,只需要依次插入待存储的字符串即可。
假设要存储的字符串集合为S={s1,s2,...,sn},首先创建一个空的字典树,然后依次将每个字符串插入到字典树中。
具体的插入操作如下:1. 从根节点开始,依次遍历字符串的每个字符。
2. 如果当前字符对应的子节点不存在,则创建一个新的子节点,并将该字符作为子节点的值。
3. 如果当前字符对应的子节点存在,则直接进入该子节点。
4. 重复步骤2和3,直到遍历完整个字符串。
5. 将最后一个字符对应的节点标记为结束节点。
通过上述步骤,可以将所有的字符串插入到字典树中。
在实际应用中,为了提高插入的效率,可以使用尾插法,即每次都从根节点开始查找,直到找到合适的位置插入新的字符。
字典树的查询操作非常简单,只需要从根节点开始,依次遍历待查询字符串的每个字符,并根据字符的值找到对应的子节点。
如果遍历完整个字符串后,最后一个字符对应的节点是一个结束节点,说明该字符串存在于字典树中;否则,该字符串不存在。
除了查询操作,字典树还可以支持前缀匹配操作。
给定一个字符串,可以找到字典树中所有以该字符串为前缀的字符串。
字典树(Trie)详解
![字典树(Trie)详解](https://img.taocdn.com/s3/m/cffd111953d380eb6294dd88d0d233d4b14e3ff3.png)
字典树(Trie)详解详解字典树(Trie)本篇随笔简单讲解⼀下信息学奥林匹克竞赛中的较为常⽤的数据结构——字典树。
字典树也叫Trie树、前缀树。
顾名思义,它是⼀种针对字符串进⾏维护的数据结构。
并且,它的⽤途超级⼴泛。
建议⼤家熟练掌握。
字典树的概念字典树,顾名思义,是关于“字典”的⼀棵树。
即:它是对于字典的⼀种存储⽅式(所以是⼀种数据结构⽽不是算法)。
这个词典中的每个“单词”就是从根节点出发⼀直到某⼀个⽬标节点的路径,路径中每条边的字母连起来就是⼀个单词。
上图理解:(标橙⾊的节点是“⽬标节点“,即根节点到这个⽬标节点的路径上的所有字母构成了⼀个单词。
)从这张图我们可以看出,字典树就是⼀棵树(emm...有些废话的嫌疑),只不过,这棵树的每条边上都有⼀个字母,然后这棵树的⼀些节点被指定成了标记节点(⽬标节点)⽽已。
这就是字典树的概念。
结合上⾯说的概念,上图所⽰的字典树包括的单词分别为:aabcbacbbcca字典树的功能根据字典树的概念,我们可以发现:字典树的本质是把很多字符串拆成单个字符的形式,以树的⽅式存储起来。
所以我们说字典树维护的是”字典“。
那么根据这个最基本的性质,我们可以由此延伸出字典树的很多妙⽤。
简单总结起来⼤体如下:1、维护字符串集合(即字典)。
2、向字符串集合中插⼊字符串(即建树)。
3、查询字符串集合中是否有某个字符串(即查询)。
4、统计字符串在集合中出现的个数(即统计)。
5、将字符串集合按字典序排序(即字典序排序)。
6、求集合内两个字符串的LCP(Longest Common Prefix,最长公共前缀)(即求最长公共前缀)。
我们可以发现,以上列举出的功能都是建⽴在“字符串集合”的基础上的。
再⼀次强调,字典树是“字典”的树,⼀切功能都是“字典”的功能。
这也为我们使⽤字典树的时候提供了⼀个准则:看到⼀⼤堆字符串同时出现,就往哈希和Trie树那边想⼀下。
字典树的实现及代码实现把上⾯的图搬下来...字典树的两种基本操作分别是建树和查询。
字典树高效处理字符串搜索和匹配
![字典树高效处理字符串搜索和匹配](https://img.taocdn.com/s3/m/c751b9a9e109581b6bd97f19227916888486b90b.png)
字典树高效处理字符串搜索和匹配字典树(Trie树)是一种特殊的树状数据结构,其主要应用于字符串的搜索和匹配。
通过将字符串按照字符的顺序构建成树形结构,字典树可以在O(K)的时间复杂度下,在大量字符串中高效地检索和匹配目标字符串。
本文将详细介绍字典树的概念、构建方式、搜索过程以及其在实际应用中的优势。
一、字典树的概念字典树,又称前缀树(Prefix Tree)或根数(Radix Tree),是一种多叉树的结构。
它的特点是每个节点包含一个字符以及对应的子节点指针,并且从根节点到任意一个叶子节点所经过的字符序列形成的字符串都是存在的。
字典树通常用于处理字符串集合的搜索和匹配,可以快速地判断一个给定的字符串是否存在于集合中。
二、字典树的构建字典树的构建过程是按照字符串的字符顺序逐步添加的。
对于每个待插入的字符串,从根节点开始,根据字符是否已经存在对应的子节点来进行分支。
如果节点已经存在,则直接跳转到下一个节点;如果节点不存在,则创建一个新的节点。
重复这个过程,直到插入完整个字符串。
三、字典树的搜索实现字典树的搜索功能是其主要应用之一。
搜索的过程是从根节点开始,根据目标字符串的字符依次向下遍历字典树的子节点。
如果出现无法匹配的情况(即某个字符没有对应的子节点),则表示目标字符串不存在于字典树中。
如果目标字符串的所有字符都能够匹配到字典树的叶子节点,就说明目标字符串存在于字典树中。
四、字典树的优势相较于其他字符串匹配算法,字典树具有一些明显的优势:1. 搜索和插入的时间复杂度都是O(K),其中K为目标字符串的长度。
这是因为字典树的每一层代表一个字符,最坏情况下需要遍历字符串的所有字符。
2. 字典树可以高效地查找具有相同前缀的字符串,因为共享相同前缀的字符串在树中的路径是重合的。
3. 字典树有助于解决大多数的字符串搜索和匹配问题,如单词的自动补全、拼写检查和统计相同前缀的字符串数量等。
五、字典树的应用场景字典树在实际应用中有广泛的应用场景,其中一些典型的应用包括:1. 单词搜索和自动补全:通过将所有的单词构建成字典树,可以快速地搜索和自动补全单词,提升用户体验。
字典树查找原理
![字典树查找原理](https://img.taocdn.com/s3/m/6087fc99b1717fd5360cba1aa8114431b90d8ee3.png)
字典树查找原理字典树(Trie树),又称前缀树或键树,是一种用于高效存储和查找字符串的数据结构。
它的查找原理基于字符串的公共前缀,可以在O(m)的时间复杂度内查找到字符串,其中m是字符串的长度。
字典树的基本结构是一个有根的树,每个节点包含若干个指向子节点的指针。
通常,一个节点对应一个字符,从根节点开始,根据字符串的每个字符依次向下遍历,直到到达字符串的最后一个字符或无法继续向下遍历为止。
字典树的插入操作是将字符串的每个字符依次插入到树中。
如果字符对应的子节点不存在,则创建一个新的节点,并将该节点与父节点连接。
重复这个过程,直到插入完整个字符串。
最后,将最后一个字符的节点标记为字符串的结束。
字典树的查找操作是从根节点开始,依次比较每个字符,根据字符找到对应的子节点,直到到达字符串的最后一个字符或无法继续向下遍历为止。
如果到达字符串的最后一个字符且该节点被标记为字符串的结束,说明字符串存在于字典树中;否则,字符串不存在。
字典树的优点是能够高效地存储和查找字符串。
它利用了字符串的公共前缀,可以大大减少存储空间和查找时间。
在字典树中,相同前缀的字符串共享相同的节点,因此可以节省存储空间。
而查找操作只需要依次比较每个字符,时间复杂度为O(m),其中m是字符串的长度,与字典树中字符串的数量无关。
字典树还可以用于前缀匹配。
通过查找某个前缀节点的子节点,可以找到以该前缀开头的所有字符串。
这在自动补全、搜索引擎和拼写检查等应用中非常有用。
然而,字典树的缺点是消耗大量的内存。
由于每个节点都需要存储指向子节点的指针,如果字符串的字符集很大,那么字典树将变得非常庞大。
此外,在构建字典树的过程中,需要频繁地动态分配内存,这可能导致内存碎片化。
为了解决字典树的内存消耗问题,可以使用压缩字典树(压缩前缀树)。
压缩字典树将只有一个子节点的节点进行合并,从而减少了存储空间。
同时,压缩字典树的查找操作也会稍微复杂一些,需要遍历字符串的每个字符,并判断是否需要跳过合并的节点。
gin 前缀树 原理
![gin 前缀树 原理](https://img.taocdn.com/s3/m/3f02d0e3ac51f01dc281e53a580216fc700a53cf.png)
gin 前缀树原理前缀树(Trie)原理什么是前缀树前缀树(Prefix Tree),也叫字典树(Trie Tree),是一种用于存储字符串集合的数据结构。
它的特点是高效地支持动态插入和搜索以及查找字符串的前缀。
前缀树的基本结构前缀树由节点和边组成,根节点表示空字符串。
每个节点代表一个字符,节点上的边代表字符的连接。
从根节点到任意节点的路径表示一个字符串。
实现前缀树节点结构每个节点包含以下几个属性: - 字符:表示节点代表的字符 - 子节点:存储下一级节点的指针 - 结尾标识:用于标识字符串的结束插入操作1.从根节点开始遍历待插入字符串的每个字符。
2.如果当前字符在当前节点的子节点中已存在,则继续遍历下一个字符。
否则,创建一个新节点,并将当前节点的子节点指向新节点。
3.遍历完所有字符后,在最后一个节点上添加结尾标识,表示字符串的结束。
搜索操作1.从根节点开始遍历待搜索的字符串的每个字符。
2.如果当前字符在当前节点的子节点中存在,则继续遍历下一个字符,否则,返回搜索失败。
3.遍历完所有字符后,如果最后一个节点上有结尾标识,则表示搜索成功;否则,表示搜索失败。
前缀树的应用前缀树常用于以下场景: - 字符串搜索和匹配 - 自动补全和提示功能 - IP路由表等网络协议中的应用前缀树的优势和注意事项优势•高效的字符串搜索和前缀查询•易于插入和删除操作•节省空间,用空间换时间注意事项•前缀树在存储大量具有相同前缀的字符串时,可以大大减少存储空间的消耗。
•随着字符串数量的增加,前缀树的内存消耗也会增加。
总结前缀树是一种高效地存储字符串集合的数据结构,可以用于字符串搜索、前缀查询等应用场景。
它的基本结构由节点和边组成,通过插入和搜索操作可以构建和利用前缀树。
前缀树的优势在于高效的字符串操作和节省空间,但随着字符串数量的增加,内存消耗也会增加。
实现前缀树的代码示例下面是使用Python语言实现前缀树的示例代码:class TrieNode:def __init__(self):= {}_end_of_word = Falseclass Trie:def __init__(self):= TrieNode()def insert(self, word):current_node =for char in word:if char not in current_:current_[char] = TrieNode()current_node = current_[char]current__end_of_word = Truedef search(self, word):current_node =for char in word:if char not in current_:return Falsecurrent_node = current_[char]return current__end_of_word上面的代码定义了两个类,TrieNode表示前缀树的节点,Trie 表示前缀树的数据结构。
字符串匹配——字典树(Trie树)、后缀树(suffix
![字符串匹配——字典树(Trie树)、后缀树(suffix](https://img.taocdn.com/s3/m/2a516013df80d4d8d15abe23482fb4daa58d1d42.png)
字符串匹配——字典树(Trie树)、后缀树(suffix tree)字典树(Trie树):它的优点是:利⽤字符串的公共前缀来减少查询时间,最⼤限度地减少⽆谓的字符串⽐较,查询效率⽐哈希表⾼。
字典树的特点:根节点不包含字符,除根节点外每⼀个节点都只包含⼀个字符;从根节点到某⼀节点,路径上经过的字符连接起来,为该节点对应的字符串;每个节点的所有⼦节点包含的字符都不相同。
字典树的创建1. 从根节点开始⼀次搜索2. 取得要查找关键词的第⼀个字母,并根据该字母选择对应的⼦树并转到该⼦树继续进⾏检索3. 在相应的⼦树上,取得要查找关键词的第⼆个字母,并进⼀步选择对应的⼦树进⾏检索4. 迭代过程...5. 在某个节点处,关键词的所有字母已被取出,则读取附在该节点上的信息,即完成查找字典树的应⽤1、字典树在串的快速检索中的应⽤#define MAX 26 //字符集⼤⼩typedef struct TrieNode {int nCount;struct TrieNode *next[MAX]; //每个节点⽤⼀个数组存储⼦节点}TrieNode;TrieNode Memory[1000000];int allocp =0;TrieNode *CreateTrieNode() {int i;TrieNode *p;p = &Memory[allocp++];p->nCount = 1;for(i =0 ; i < MAX ; i++) {p->next[i] = NULL;}return p;}void InsertTrie(TrieNode * &pRoot , char*s) { //插⼊ & 建树int i, k;TrieNode *p;if(!(p = pRoot)) {p = pRoot = CreateTrieNode();}i = 0;while(s[i]) {k = s[i++] - 'a';if(p->next[k])p->next[k]->nCount++;elsep->next[k] = CreateTrieNode();p = p->next[k];}}int SearchTrie(TrieNode * &pRoot , char*s) { //查询单词的出现次数TrieNode *p;int i , k;if(!(p = pRoot)) {return 0;}i = 0;while(s[i]) {k = s[i++] -'a';if(p->next[k] == NULL) return 0;p = p->next[k];}return p->nCount;}2. 字典树在“串”排序⽅⾯的应⽤给定N个互不相同的仅由⼀个单词构成的英⽂名,让你将他们按字典序从⼩到⼤输出⽤字典树进⾏排序,采⽤数组的⽅式创建字典树,这棵树的每个结点的所有⼉⼦很显然地按照其字母⼤⼩排序。
前缀树的原理及实现
![前缀树的原理及实现](https://img.taocdn.com/s3/m/e5be7be877eeaeaad1f34693daef5ef7ba0d122f.png)
前缀树的原理及实现前缀树,也称为字典树或者Trie树,是一种非常常用的数据结构,用于存储和查找字符串集合。
它的特点之一是能够高效地支持字符串的前缀匹配。
本文将详细介绍前缀树的原理以及实现。
一、前缀树的原理前缀树是一种多叉树的数据结构,它的每个节点代表一个字符,从根节点到叶子节点可以构成一个完整的字符串。
每个节点都有若干子节点,每个子节点代表一个字符。
在前缀树中,根节点不代表任何字符,它的子节点表示第一个字符,再往下的节点表示第二个字符,以此类推。
通过节点之间的连接关系,可以将字符串集合存储在前缀树中。
举个例子来说明,假设有一个字符串集合["apple", "banana", "abacus", "book", "bat"]需要存储在前缀树中。
首先创建一个根节点,由于根节点不代表任何字符,所以它的子节点表示第一个字符。
第一步,将字符串集合中的第一个字符串"apple"存入前缀树中。
从根节点开始,依次插入字符,如果节点中不存在该字符的子节点,则新建一个子节点,否则继续向下寻找。
最后一个字符插入后,以该节点为终止节点,表示该字符串插入完成。
第二步,重复上述操作,将剩下的字符串插入前缀树中。
最终得到如下的前缀树:root/ \a b b/p a o/ / \p c k o/ /l ue s t ‡/ \‡‡ e a/ \‡‡图中的`‡`表示一个字符串的结束字符。
通过这样的存储方式,我们可以方便地进行前缀匹配操作。
例如,如果要查找"app",只需要从根节点开始,根据字符"a"找到下一个节点,然后根据字符"p"找到下一个节点,依次类推,直到最后一个字符。
如果最后一个节点为`‡`,则表示前缀匹配成功。
二、前缀树的实现接下来,我们将通过Java代码来实现前缀树。
字典树数据结构中的高效字符串匹配算法
![字典树数据结构中的高效字符串匹配算法](https://img.taocdn.com/s3/m/e83375aa846a561252d380eb6294dd88d0d23d09.png)
字典树数据结构中的高效字符串匹配算法字典树(Trie树)是一种针对字符串快速检索的数据结构。
它通过利用字符串的公共前缀来进行高效的模式匹配与搜索。
在本文中,我们将深入探讨字典树的原理和应用,以及如何使用字典树实现高效的字符串匹配算法。
一、字典树的定义与基本原理字典树,又称为前缀树或Trie树,是一种多叉树结构。
它的每个节点代表一个字符串的前缀,根节点为空字符串。
字典树的核心思想是通过节点间的连接关系来表示字符串之间的前缀关系。
字典树的构建过程即为不断插入字符串的过程。
对于要插入的字符串,从根节点开始,依次判断每个字符是否在当前节点的子节点中存在。
如果存在,则移动到该子节点进行判断;如果不存在,则创建一个新的子节点。
重复此过程,直到字符串的所有字符都插入完毕。
二、字典树的应用1. 单词查找字典树可以用来快速查找某个单词是否存在于给定的词汇表中。
通过构建字典树,我们可以有效地判断一个单词是否存在,而不需要遍历整个词汇表。
2. 字符串匹配在文本编辑器、编译器等应用中,需要对大量字符串进行模式匹配操作。
字典树可以高效地实现字符串的前缀匹配与搜索。
三、基于字典树的字符串匹配算法一种基于字典树的高效字符串匹配算法是AC自动机算法。
AC自动机算法在字典树的基础上进行了优化,可以在较短的时间内完成多个模式串的匹配。
AC自动机的构建过程包括两个关键步骤:构建字典树和添加失败指针。
具体步骤如下:1. 构建字典树- 遍历所有模式串,将它们逐个插入字典树中。
- 在插入过程中,为每个节点添加一个is_end标志,用于表示该节点是否为模式串的末尾节点。
2. 添加失败指针- 对于字典树的每个节点,设置一个失败指针,指向当前节点的失败节点。
- 失败节点指的是,从根节点到当前节点组成的路径所代表的字符串的最长真后缀,同时也是某个模式串的真前缀。
经过以上两个步骤,AC自动机的构建完成。
接下来,可以通过遍历文本串来进行字符串的匹配。
字典树高效的字符串匹配算法
![字典树高效的字符串匹配算法](https://img.taocdn.com/s3/m/8a280f9251e2524de518964bcf84b9d528ea2c2e.png)
字典树高效的字符串匹配算法字典树(Trie树),也叫做前缀树,是一种高效的字符串匹配算法。
它通过利用字符串之间的公共前缀,将相同前缀的字符串存储在一起,以节省内存空间并提高查找效率。
本文将介绍字典树的定义、构建方法,以及其在字符串匹配中的应用。
一、字典树的定义字典树是一种多叉树,每个节点包含一个指向下一个节点的指针数组。
其中,指针数组的长度等于字符的种类数目,而每个指针的下标则对应不同的字符。
在根节点到叶子节点的每一条路径上,都代表一个字符串。
二、字典树的构建1. 初始化字典树我们首先创建一个空的根节点,并将指针数组初始化为空。
2. 添加字符串对于每个要添加的字符串,我们从根节点开始,按照字符串中的字符逐层创建相应的节点,并将指针连接起来。
如果某个字符节点已经存在,则直接跳转到对应的节点。
直到字符串中的所有字符都添加完毕。
3. 设置结束标志当一个字符串添加完成后,在最后一个字符所在的节点中,设置一个结束标志,表示该节点所代表的字符串是一个完整的字符串。
三、字典树的应用字典树在字符串匹配中有着广泛的应用,特别是对于大量字符串的模式匹配。
下面介绍字典树在字符串匹配中的两种常用应用。
1. 判断字符串是否存在我们可以利用字典树来判断一个字符串是否存在于字典中。
具体操作如下:- 从根节点开始,按字符串中的字符顺序逐层匹配,若路径断开,则说明字典中不存在这个字符串。
- 如果匹配到了最后一个字符,并且该字符所在的节点设置了结束标志,那么说明这个字符串存在于字典中。
2. 查找前缀字符串字典树还可以用来查找满足某一前缀的字符串集合。
具体操作如下:- 从根节点开始,按前缀字符串中的字符顺序逐层匹配,若路径断开,则说明不存在满足该前缀的字符串。
否则,继续深入下一个节点。
- 当匹配到前缀字符串的最后一个字符时,我们从该节点开始,利用深度优先搜索(DFS)来遍历其后续节点,将所有满足前缀的字符串添加到结果集中。
四、字典树的优势相比于其他字符串匹配算法,字典树有如下优势:1. 快速定位:字典树的查找操作复杂度与字符串长度无关,而是与字典中字符串的数量有关。
前缀树算法
![前缀树算法](https://img.taocdn.com/s3/m/f5e6fb05905f804d2b160b4e767f5acfa1c78303.png)
前缀树算法
前缀树算法,也叫字典树、Trie树或键树,是一种多叉树结构,是一种哈希树的变种,用于存储关联数组,其中的键通常是字符串。
它的优势在于,相比于一般的哈希表,提供了更高的查找效率,特别是在一组字符串中查找某一个字符串的时候。
前缀树的结构是以一个根节点开始的,根节点不包含字符,除根节点外每一个节点都只包含一个字符。
每个节点有若干棵子树,有几个字符就有几棵子树,每棵子树代表这个节点的一个孩子节点。
其最大的特点是将相同的前缀路径归纳在一棵树上,节省了空间。
前缀树的应用很广,最常见的应用之一就是用来实现搜索引擎的搜索功能,它可以快速的查询出搜索关键字,这样就可以很快的提供搜索结果,从而提高搜索的效率。
此外,前缀树算法还可以用于语音识别、字符串匹配等场景。
前缀树算法的优势在于,它可以把多个相同前缀的字符串映射到一棵树上,节省空间,查找效率也比较高,特别是对于有很多相同前缀的字符串,前缀树算法可以有效的减少搜索时间,提高搜索效率。
前缀树算法也有一些缺点,它在构建树的时候需要消耗大量的时间,这可能是因为它的搜索效率比较高,因此它的预处理需要花费更多的时间。
另外,每个节点都需要记录一个字符,如果字符集很大的话,存储空间也会增加很多。
总的来说,前缀树算法能够提高搜索效率,节省空间,但是在构建树的时候会需要较长的时间,如果字符集很大也会占用更多的存储空间。
然而,前缀树算法仍然是一种重要的算法,用于字符串匹配、搜索引擎搜索等方面,可以说是一种非常有效的算法。
后缀树和后缀数组
![后缀树和后缀数组](https://img.taocdn.com/s3/m/28b27802dc36a32d7375a417866fb84ae45cc360.png)
后缀树和后缀数组基本概念子串:字符串S的子串S[i..j],i?j,表示S串中从i到j这一段,也就是顺次排列S[i],S[i+1],...,S[j]形成的字符串。
字符集:一个字符集Σ是一个建立了全序关系的集合,也就是说,Σ中的任意两个不同的元素α和β都可以比较大小,要么α<β,要么β<α(也就是α>β)。
字符集Σ中的元素称为字符。
字符串:一个字符串S是将n个字符顺次排列形成的数组,n称为S的长度,表示为len(S)。
S的第i个字符表示为S[i]。
子串:字符串S的子串S[i..j],i?j,表示S串中从i到j这一段,也就是顺次排列S[i],S[i+1],...,S[j]形成的字符串。
后缀:后缀是指从某个位置i开始到整个串末尾结束的一个特殊子串。
字符串S 的从i开头的后缀表示为Suffix(i),也就是Suffix(i)=S[i..len(S)] 例如S = mississippi,那么它的所有后缀为:Suffix(1) = mississippi = SSuffix(2) = ississippiSuffix(3) = ssissippiSuffix(4) = sissippiSuffix(5) = issippiSuffix(6) = ssippiSuffix(7) = sippiSuffix(8) = ippiSuffix(9) = ppiSuffix(10) = piSuffix(11) = iSuffix(12) = (empty)不难发现,S的任意一个子串一定是某一个后缀的前缀。
字符串的大小比较:指通常所说的“字典顺序”比较,也就是对于两个字符串u、v,令i从1开始顺次比较u[i]和v[i],如果u[i]=v[i]则令i加1,否则若u[i]<v[i]则认为u<v,u[i]>v[i]则认为u>v(也就是v<u),比较结束。
如果i>len(u)或者i>len(v)仍比较出结果,那么若len(u)<len(v)则认为u<v,若len(u)=len(v)则认为u=v,若len(u)>len(v)则u>v。
字典树高效的字符串检索工具
![字典树高效的字符串检索工具](https://img.taocdn.com/s3/m/ad7f4be2d0f34693daef5ef7ba0d4a7302766c8b.png)
字典树高效的字符串检索工具字典树,也称为前缀树或Trie树,是一种常用的数据结构,用于快速检索字符串。
它能够有效地解决字符串查找的问题,特别适用于大量字符串的存储与检索。
本文将介绍字典树的结构、功能以及应用场景,以展示字典树作为高效的字符串检索工具的优势。
一、字典树的结构和基本功能字典树是一种多叉树,其中每个节点包含一个字符,节点之间通过指针连接。
根节点不包含字符,每个节点除了存储字符外,还有一个布尔变量用来标记该节点是否为某个字符串的结束位置。
通过从根节点开始沿着指针路径不断遍历,可以得到完整的字符串。
字典树具有以下基本功能:1. 字符串的插入:将一个字符串插入到字典树中,从根节点开始,逐级查找该字符串是否已经存在对应节点,若存在则不进行插入,若不存在则创建新节点,并将对应字符插入到新节点中。
2. 字符串的搜索:从根节点开始,逐级查找目标字符串,若能够找到完整字符串,则返回true,否则返回false。
3. 字符串的前缀搜索:从根节点开始,逐级查找目标字符串的前缀,若能够找到,则返回true,否则返回false。
二、字典树的应用场景字典树在各种应用中都有广泛的应用,下面列举几个常见的应用场景来展示其高效的字符串检索能力。
1. 搜索引擎关键词提示:搜索引擎可以利用字典树快速地根据用户的输入进行关键词提示,通过构建字典树,将所有关键词存储在树中,用户每输入一个字符,就通过字典树进行搜索,给出可能的关键词提示,提高搜索的效率和准确性。
2. 单词拼写检查:字典树可以用来进行单词拼写的检查。
用户输入一个单词后,可以通过字典树进行匹配,若匹配成功则表示单词正确,若匹配失败则表示单词拼写错误,并给出可能的正确单词建议。
3. 模式匹配:字典树可以用来进行模式匹配,例如在一个文本中查找多个关键词。
通过将所有关键词构建成字典树,然后从文本起始位置开始,逐个字符在字典树中进行搜索,若能够找到完整的关键词,则表示匹配成功。
字符串前缀、后缀、子串、字典树
![字符串前缀、后缀、子串、字典树](https://img.taocdn.com/s3/m/0eccd54024c52cc58bd63186bceb19e8b8f6ec8a.png)
字符串前缀、后缀、子串、字典树Sicily 1426. Phone List(判断电话号码是否前缀重复)Sample Input2391197625999911254265113123401234401234598346Sample OutputNOYES/*用string 类型数组读进所有电话号码,然后用sort 函数对其进行排序。
排序与每个号码的长短无关(前面相同的较短的较小),而是从首位开始逐位比较。
如对13,123,124,11456使用sort函数进行排序,结果会是11456,123,124,13这样排序之后如果有不相容的两个号码肯定会出现在相邻的两位了,所以对整个数组所有相邻的两位逐位进行比对即可得到结果。
*/ #include#includeusing namespace std;int main(){inttestcases;//测试数cin>>testcases;while(testcases--){intnum_of_phone_number;//号码数bool consistent=true;//If two numbers are found inconsistent,it will be falsecin>>num_of_phone_number;string numbers[num_of_phone_number];//号码存放数组for(inti=0;i<="">cin>>numbers[i];}sort(numbers,numbers+num_of_phone_number);//排序//Now if inconsistent numbers exist,they must be adjacent for(inti=0;i<="" p="" search="" two="">intlen=numbers[i].length();bool match=true; for(int j=0;j<len;j++){< p="">if(numbers[i][j]!=numbers[i+1][j]){match=false;break;}}if(match){cout<<"NO"<<endl;< p="">consistent=false;break;}}if(consistent)cout<<"YES"<<endl;< p="">}return 0;}方法2#include#include#includeusing namespace std;int main(){string s[ 10000 ];int t, n;inti;bool find;cin>> t;while ( t-- ) {cin>> n;for ( i = 0; i< n; i++ )cin>> s[ i ];sort( s, s + n );find = false;for ( i = 1; i< n; i++ ) {if ( s[ i ].find( s[ i - 1 ] ) != string::npos ) { find = true; break;}}cout<< ( find ? "NO": "YES" )<<endl;< p="">}return 0;}方法3#include#include#includeusing namespace std;int main(){inttestcase;stringarr[20001];cin>>testcase;while(testcase--){intphonenum;cin>>phonenum;for(inti =0;i<phonenum;i++)< p=""> cin>>arr[i];sort(arr,arr+phonenum);bool is = false;for (int j=0;j<="" p="">{if (arr[j].size()<= arr[j+1].size()){if (arr[j] ==arr[j+1].substr(0,arr[j].size())) {cout<<"NO"<<endl;< p="">is = true;break;}}}if (!is)cout<<"YES"<<"\n";}return 0;}1198 字典序题目要求输出的组合字符串具有最小字典序,其实就是把题目给出的字符串进行排序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
return a+b<b+a;;
}
int main()
{
int t;
cin>>t;
string s[8];
while(t)
{inΒιβλιοθήκη n;cin>>n;
for(int i=0;i<n;i++)
{
cin>>s[i];
}
sort(s,s+n,comp);
for(int i=0;i<n;i++)
cout<<s[i];
bool find;
cin >> t;
while ( t-- ) {
cin >> n;
for ( i = 0; i < n; i++ )
cin >> s[ i ];
sort( s, s + n );
find = false;
for ( i = 1; i < n; i++ ) {
if ( s[ i ].find( s[ i - 1 ] ) != string::npos ) {
cout<<"YES"<<endl;
}
return 0;
}
方法2#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string s[ 10000 ];
int t, n;
int i;
}
for(i=0;i<N;i++)
cout<<str[i];
cout<<endl;
}
return 0;
}
方法2:#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
bool comp(string a,string b)
{
int testcase;
string arr[20001];
cin >> testcase;
while(testcase--)
{
int phonenum;
cin >>phonenum;
for(int i =0;i<phonenum;i++)
cin>>arr[i];
sort(arr,arr+phonenum);
bool match=true;
for(int j=0;j<len;j++){
if(numbers[i][j]!=numbers[i+1][j]){
match=false;
break;
}
}
if(match){
cout<<"NO"<<endl;
consistent=false;
break;
}
}
if(consistent)
break;
}
}
}
if (!is)
cout<<"YES"<<"\n";
}
return 0;
}
1198字典序题目要求输出的组合字符串具有最小字典序,其实就是把题目给出的字符串进行排序。考虑输入只有两个字符串s1和s2的情况,要输出s1和s2组合的最小字典序,只需要比较s1+s2和s2+s1这两个字符串哪个的字典序更小即可。扩展到多个字符串的情况也是一样的。
find = true;
break;
}
}
cout << ( find ? "NO": "YES" ) << endl;
}
return 0;
}
方法3
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
排序与每个号码的长短无关(前面相同的较短的较小),而是从首位开始逐位比较。
如对13,123,124,11456使用sort函数进行排序,结果会是11456,123,124,13
这样排序之后如果有不相容的两个号码肯定会出现在相邻的两位了,所以对整个数组所有相邻的两位逐位进行比对即可得到结果。*/
#include<iostream>
cin>>num_of_phone_number;
string numbers[num_of_phone_number];//号码存放数组
for(int i=0;i<num_of_phone_number;i++){//输入号码
cin>>numbers[i];
}
sort(numbers,numbers+num_of_phone_number);//排序
Sicily 1426. Phone List(判断电话号码是否前缀重复)
Sample Input
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
Sample Output
NO
YES/*用string类型数组读进所有电话号码,然后用sort函数对其进行排序。
cin>>str[i];
for(i=0;i<N;i++)
for(j=i+1;j<N;j++)
{
if(str[i]+str[j]>str[j]+str[i])
str[i].swap(str[j]);
//若str[i]为b,str[j]为ba,如果仅仅是判断str[i]>str[j],那结果是bba,但正确的应该是bab,所以条件要加强为str[i]+str[j]>str[j]+str[i]
//Now if inconsistent numbers exist,they must be adjacent
for(int i=0;i<num_of_phone_number-1;i++){//linear search every two numbers
int len=numbers[i].length();
#include<algorithm>
using namespace std;
int main(){
int testcases;//测试数
cin>>testcases;
while(testcases--){
int num_of_phone_number;//号码数
bool consistent=true;//If two numbers are found inconsistent,it will be false
#include<iostream>
#include <string>
#include<cstdio>
using namespace std;
int main()
{
int T,N,l,i,j;
string str[8];
cin>>T;
for(l=0;l<T;l++)
{
scanf("%d",&N);
for(i=0;i<N;i++)
bool is = false;
for (int j=0;j<phonenum -1;j++)
{
if (arr[j].size()<= arr[j+1].size())
{
if (arr[j] ==arr[j+1].substr(0,arr[j].size()))
{
cout<<"NO"<<endl;
is = true;
cout<<endl;
t--;
}
return 0;
}