传送门:hdu 5687 Problem C
中文题目就不做过多的解释
解题思路
定义一个结构体,里面有26个字母,就像下面这样:
struct Node{int next[26];int sum;void init(){sum = 0;memset(next,-1,sizeof next);}
};
然后定义一个这个类型root[MAXN]数组,表示到每个单词的编号,比如root[1].next[0] = x,就表示当前节点连接的下一个节点是0通过x到达。
增加函数
就不用过多赘述了,因为几本书与模板类型。
查询函数
建议返回的是查询单词字母一个出现了多少个,因为这样会方便删除操作
删除函数
就是将这个单词对应的路上删除对应的数量
AC代码
#include<cstdio>
#include<cstring>
const int MAXN = 1200500;
int tot = 1;
struct Node{int next[26];int sum;void init(){sum = 0;memset(next,-1,sizeof next);}
};
Node root[MAXN];
void add(char *str)
{int len = strlen(str);int start = 0;for(int i=0;i<len;i++){int id = str[i] - 'a';if(root[start].next[id] == -1){root[start].next[id]=tot++;}start = root[start].next[id];root[start].sum++;}
}
int search(char *str)
{int len = strlen(str);int start = 0;for(int i=0;i<len;i++){int id = str[i] - 'a';if(root[start].next[id] == -1)return 0;start = root[start].next[id];}return root[start].sum;
}
void del(char *str,int cnt)
{int len = strlen(str);int start = 0;if(cnt<0) return ;for(int i=0;i<len;i++){int id = str[i] - 'a';if(root[start].next[id] == -1)return ;root[start].sum-=cnt;start = root[start].next[id];}root[start].sum = 0;for(int i=0;i<26;i++)root[start].next[i] = -1;
}int main()
{int T;char str[10],word[35];scanf("%d",&T);for(int i=0;i<MAXN;i++)root[i].init();while(T--){scanf("%s%s",str,word);if(str[0] == 'i')add(word);else if(str[0] == 's')if(search(word)>0) printf("Yes\n");else printf("No\n");elsedel(word,search(word));}return 0;
}
我同学用动态申请内存的方法AC代码
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define FIN freopen("in.txt", "r", stdin);
#define FOUT freopen("out.txt", "w", stdout);
#define lson l, mid, cur << 1
#define rson mid + 1, r, cur << 1 | 1
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int MAXN = 1e2 + 50;
const int MAXM = 1e5 + 50;
const int MOD = 1e9 + 7;struct node
{int v;node* nxt[26];node(){v = 0;memset(nxt, NULL, sizeof(nxt));}
};void trie_insert(node* root, char* word)
{node* now = root;int len = strlen(word);for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)now->nxt[id] = new node();now = now->nxt[id];now->v++;}
}void trie_delete(node* root, char* word)
{node* now = root;int len = strlen(word), del;for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)return;now = now->nxt[id];del = now->v;}now = root;for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)return;if (i == len - 1){free(now->nxt[id]);now->nxt[id] = NULL;return;}now = now->nxt[id];now->v -= del;}
}bool trie_query(node* root, char* word)
{node* now = root;int len = strlen(word);int ans = INF;for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)return false;now = now->nxt[id];}return now->v != 0;
}int main()
{int n;scanf("%d", &n);char op[35], word[35];node* root = new node();while (n--){scanf("%s%s", op, word);if (strcmp(op, "insert") == 0)trie_insert(root, word);else if (strcmp(op, "delete") == 0)trie_delete(root, word);elseprintf("%s\n", trie_query(root, word) ? "Yes" : "No");}return 0;
}