题目描述

人们在英文字典中查找某个单词的时候可能不知道该单词的完整拼法,而只知道该单词的一个错误的近似拼法,这时人们可能陷入困境,为了查找一个单词而浪费大量的时间。带有模糊查询功能的电子字典能够从一定程度上解决这一问题:用户只要输入一个字符串,电子字典就返回与该单词编辑距离最小的几个单词供用户选择。

字符串a与字符串b的编辑距离是指:允许对a或b串进行下列“编辑”操作,将a变为b或b变为a,最少“编辑”次数即为距离。

  1. 删除串中某个位置的字母;
  2. 添加一个字母到串中某个位置;
  3. 替换串中某一位置的一个字母为另一个字母;

JSOI团队正在开发一款电子字典,你需要帮助团队实现一个用于模糊查询功能的计数部件:对于一个待查询字符串,如果它是单词,则返回-1;如果它不是单词,则返回字典中有多少个单词与它的编辑距离为1。

输入输出格式

输入格式:

第一行包含两个正整数N (N ≤ 10,000)和M (M ≤ 10,000)。

接下来的N行,每行一个字符串,第i + 1行为单词Wi。单词长度在1至20之间。

再接下来M行,每行一个字符串,第i + N + 1表示一个待查字符串Qi。待查字符串长度在1至20之间。Wi和Qi均由小写字母构成,文件中不包含多余空格。所有单词互不相同,但是查询字符串可能有重复。

输出格式:

输出应包括M行,第i行为一个整数Xi。Xi = -1表示Qi为字典中的单词;否则Xi表示与Qi编辑距离为1的单词的个数。


emmmmm, 据说是trie树, 不是很会呀, 勉强用hash搞一下吧; 首先存下每个单词的hash值, 排序是为了以后的查找。 依次读入每一个单词, 再用前缀和后缀和记录hash值,用二分查找是否存在, 存在即返回, 依次如题目所示枚举删除、添加、替换的点, 找到即ans++, 其中一些情况不必再次查找, 如类似aab的情况,删去两个a的效果是一样;最后输出即可;

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + ;
const int MAXM = 3e3 + ; template < typename T > inline void read(T &x) {
x = ; T ff = , ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') ff = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + (ch ^ );
ch = getchar();
}
x *= ff;
} template < typename T > inline void write(T x) {
if(x < ) putchar('-'), x = -x;
if(x > ) write(x / );
putchar(x % + '');
} int n, m;
ull h[MAXN], p[], s1[], s2[];
char s[]; inline bool find(ull x) {
int l = , r = n;
while(l < r) {
int mid = ((l + r) >> );
if(h[mid] >= x) r = mid;
else l = mid + ;
}
return h[l] == x;
} int main() {
read(n); read(m); p[] = ;
for(register int i = ; i <= ; ++i)
p[i] = p[i - ] * ;
for(register int i = ; i <= n; ++i) {
scanf("%s", s + );
int len = strlen(s + );
for(register int j = ; j <= len; ++j)
h[i] = h[i] * + (s[j] - 'a' + );
} sort(h + , h + n + ); while(m--) {
scanf("%s", s + );
int len = strlen(s + ), ans = ;
s2[len + ] = ;
for(register int i = ; i <= len; ++i)
s1[i] = s1[i - ] * + (s[i] - 'a' + ); if(find(s1[len])) {
write(-);
putchar('\n');
continue;
}
for(register int i = len; i >= ; --i)
s2[i] = s2[i + ] + (s[i] - 'a' + ) * p[len - i]; for(register int i = ; i < len; ++i)
if(s[i] != s[i + ])
if(find(s1[i] * p[len - i - ] + s2[i + ])) ++ans; //删除 for(register int i = ; i <= len; ++i)
for(register int j = ; j <= ; ++j)
if(j != (s[i] - 'a' + ))
if(find(s1[i] * p[len - i + ] + j * p[len - i] + s2[i + ])) ++ans; //添加 for(register int i = ; i <= len; ++i)
for(register int j = ; j <= ; ++j)
if(j != (s[i] - 'a' + ))
if(find(s1[len] + (j - (s[i] - 'a' + )) * p[len - i])) ++ans; //替换 printf("%d\n", ans); }
return ;
}

最新文章

  1. SQL初步知识点
  2. 关于phpstorm中安装配置xdeug
  3. 5-JS函数
  4. cocos2dx 内存管理机制
  5. bzoj3555: [Ctsc2014]企鹅QQ
  6. 补充:sql server 中的相关查询、case函数
  7. 全国各城市Uber客服联系方式(电话、邮箱、微博)
  8. asp.net mvc4 远程验证
  9. 读取本地文件理解FileReader对象的方法和事件以及上传按钮的美化。
  10. rpc接口调用以太坊智能合约
  11. Kubernetes之服务发现及负载Services
  12. 使用Spring提供的缓存抽象机制整合EHCache为项目提供二级缓存
  13. os.path的使用
  14. unity3d-代码控制游戏角色控制器移动
  15. 20155228 实验三 敏捷开发与XP实践
  16. navicat ora-28547:connection to server failed
  17. hdu 5068 线段树加+dp
  18. mongo学习- mapReduce操作事例
  19. aar
  20. [ActionScript 3.0] 动态链接库

热门文章

  1. jzyz集训 0611
  2. JMS消息可靠机制
  3. 算法(Algorithms)第4版 练习 1.3.219
  4. 分享知识-快乐自己:SpringMvc中的单多文件上传及文件下载
  5. SoundHound Inc. Programming Contest 2018
  6. poj 2689Prime Distance(区间素数)埃氏筛法
  7. 1070 Bash 游戏 V4
  8. 闪回之 Flashback Query (dml表、过程、函数、包等)、Flashback version Query
  9. TTY,Console以及Terminal
  10. VijosP1443:银河英雄传说