题目
福尔摩斯从X星收到一份资料,全部是小写字母组成。
他的助手提供了另一份资料:许多长度为8的密码列表。
福尔摩斯发现,这些密码是被打乱后隐藏在先前那份资料中的。
请你编写一个程序,从第一份资料中搜索可能隐藏密码的位置。要考虑密码的所有排列可能性。
输入
输入第一行:一个字符串s,全部由小写字母组成,长度小于1024*1024
紧接着一行是一个整数n,表示以下有n行密码,1<=n<=1000
紧接着是n行字符串,都是小写字母组成,长度都为8
输出
一个整数, 表示每行密码的所有排列在s中匹配次数的总和。
样例输入
aaaabbbbaabbcccc
2
aaaabbbb
abcabccc
样例输出
4
解题思路
首先读入原字符串和密码数目,之后每读入一行8位的密码,进行一次qsort排序,并以hash散列统计出现了哪些字母,之后遍历原字符串,如果遍历到的当前字符(char)在8位密码中出现过,那么读入当前字符之后8位(包含当前字符),qsort后和8位密码比较,若相等,则匹配次数加一。如此循环,直到所有密码都被判断完毕,输出匹配次数。
代码
#include<bits/stdc++.h>
using namespace std;
int cmp(const void *a, const void *b){
return *(char *)a - *(char *)b;//升序
}
int main()
{
int num = 0;
int n,k,i,j;//n行密码
char b[9],temp[9];//长度为8的密码
int Hash[26];//存储某个字母是否出现
string a;
cin >> a >> n;
for (i=0;i<n;i++)
{
scanf("%s",b);
qsort(b,8,sizeof(char),cmp);
for (j=0;j<26;j++)//初始化
Hash[j] = 0;
for (j=0;j<8;j++)//把出现在密码中的字符赋为1
Hash[b[j]-97] = 1;
for (j=0;j<(a.size()-7);j++)//遍历搜索
{
if (Hash[a[j]-97]==1)
{
for (k=j;k<(j+8);k++)
temp[k-j] = a[k];
temp[8] = '\0';
qsort(temp,8,sizeof(char),cmp);
if (strcmp(temp,b)==0)
num++;
}
}
}
printf("%d",num);
return 0;
}