老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀)
就是一个简单的字典树的题,写个字典树就OK了,但是要注意,解题的时候的字典树注意要尽量避免去使用动态开内存的情况,因为,内存可能会爆炸,题目中也说了。只有50000个单词,每个单词最多10个字符,那么也就是说,字典树中最多只有500000个节点,我们直接将这些节点开出来就可以了
代码实现
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
typedef struct node{
// 记录在trie上经过当前节点的字符串的数量
int count;
char flag;
int next[26];
}Node;
Node root;
int use = 1;
Node nodes[500005];
void init(Node* node){
for(int i=0;i<26;i++){
node->next[i] = 0;
}
node->count = 1;
node->flag = 0;
}
void insert(char *str){
Node* cur = &root;
for(int i=0;str[i];i++){
int c = str[i] - 'a';
if(cur->next[c]){
cur = &nodes[cur->next[c]];
cur->count++;
}else{
Node* newNode = &nodes[use];
init(newNode);
cur->next[c] = use++;
cur = newNode;
}
}
cur->flag = 1;
}
int query(char * str){
Node* cur = &root;
for(int i=0;i<str[i];i++){
int c = str[i] - 'a';
if(cur->next[c]){
cur = &nodes[cur->next[c]];
}else{
return 0;
}
}
return cur->count;
}
int main(){
printf("%d",sizeof(Node));
char s[12];
int len;
init(&root);
while(gets(s)){
if(s[0] == '\0'){
break;
}
insert(s);
}
while(gets(s)){
printf("%d\n",query(s));
}
}
这个就是爆空间的代码
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
typedef struct node{
int count;
char flag;
int next[26];
}Node;
Node root;
int use = 1;
Node nodes[500005];
void init(Node* node){
for(int i=0;i<26;i++){
node->next[i] = 0;
}
node->count = 1;
node->flag = 0;
}
void insert(char *str){
Node* cur = &root;
for(int i=0;str[i];i++){
int c = str[i] - 'a';
if(cur->next[c]){
cur = &nodes[cur->next[c]];
cur->count++;
}else{
Node* newNode = &nodes[use];
init(newNode);
cur->next[c] = use++;
cur = newNode;
}
}
cur->flag = 1;
}
int query(char * str){
Node* cur = &root;
for(int i=0;i<str[i];i++){
int c = str[i] - 'a';
if(cur->next[c]){
cur = &nodes[cur->next[c]];
}else{
return 0;
}
}
return cur->count;
}
int main(){
printf("%d",sizeof(Node));
char s[12];
int len;
init(&root);
while(gets(s)){
if(s[0] == '\0'){
break;
}
insert(s);
}
while(gets(s)){
printf("%d\n",query(s));
}
}