标签:头插法 实现 ext str1 否则 ini while 传送门 init
给出nm个字符串,进行nm次连接,输出连接后的字符串有几种
传送门
对于插入,查询字符串的种类有几个操作
scanf不能输入\0要用gets()
scanf不能输入string要用cin
hash,next都是关键词
由于hash的数目很大
/*链式哈希表
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1e6;
int n,m;
string str1[maxn];
string str2[maxn];
string allstr[maxn];
int head[maxn],Next[maxn];
int ans,cnt;
int gethash(string str){
int seed=131;//哈希基底
int hashvalue=0;//哈希值
for(int i=0;i<str.size();i++){
hashvalue=hashvalue*seed+str[i];//hash表达式
}
return (hashvalue&0x7FFFFFFF)%maxn;//一个对象的hashcode可能是负数,这样操作后使得其为正数,且防止溢出
}
int insert_table(int s){//头插法链表
int h=gethash(allstr[s]);//获得该字符串的hash
int u=head[h];//u就是该字符串哈希值的前面的下标
while(u){//如果下标不为0
if(allstr[u]==allstr[s])return 0;
u=Next[u];//下一个
}
//否则插入到链表里面
Next[s]=head[h];//链表往回移动一位
head[h]=s;//更新表头
return 1;
}
void init(){
ans=0;
cnt=1;
memset(head,0,sizeof(head));
memset(Next,0,sizeof(next));
}
int main(){
int t;
scanf("%d",&t);
rep(k,1,t){
init();
scanf("%d%d",&n,&m);
rep(i,1,n){
cin>>str1[i];//不能用scanf,因为string不是%s
}
rep(i,1,m){
cin>>str2[i];
}
string str;
rep(i,1,n){
rep(j,1,m){
str=str1[i]+str2[j];
allstr[cnt]=str;
if(insert_table(cnt))ans++;//插入成功
cnt++;
}
}
printf("Case %d: %d\n",k,ans);
}
return 0;
}
同时,对于set也可以实现该操作
#include <iostream>
#include <cstdio>
#include <set>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1e6;
set<string> s;
string str1[maxn];
string str2[maxn];
void init(){
s.clear();
}
int main(){
int t;
scanf("%d",&t);
rep(k,1,t){
init();
int n,m;
scanf("%d%d",&n,&m);
rep(i,1,n){
cin>>str1[i];
}
rep(i,1,m){
cin>>str2[i];
}
string str;
rep(i,1,n){
rep(j,1,m){
str=str1[i]+str2[j];
s.insert(str);
}
}
printf("Case %d: %d\n",k,s.size());
}
}
标签:头插法 实现 ext str1 否则 ini while 传送门 init
原文地址:https://www.cnblogs.com/Emcikem/p/11621661.html