《算法笔记》学习记录 Part 6 字符串专题

第十二章 字符串专题


12.1 字符串hash进阶

字符串hash是将一个字符串S映射为一个整数,使得该整数可以尽可能唯一地代替字符串S。

使用散列函数,H[i] = ( H[i-1] * 26 + index(str[i])  ) % mod

通过这种方式把字符串转换成范围上能接受的整数,在实践中发现,在int数据范围内,如果把进制数设为为一个10^7级别的素数p(如10000019),同时把mod设置为一个10^9级别的素数(如1000000007),那么冲突的概率回很小

H[i] = ( H[i-1] * p + index(str[i]) ) % mod

问题一:给出N个只有小写字母的字符串,求其中不同的字符串的个数。

#include 
#include 
#include 
#include 
using namespace std;
const int MOD = 1000000007;
const int P = 10000019;
vector ans;
//字符串hash
long long hashFunc(string str){
	long long H = 0; //使用long long 避免移除
	for(int i=0;i

问题二:输入两个长度均不超过1000的字符串,求它们的最长公共子串的长度

可以先分别对两个字符串的每个字符串求出hash值(同时记录对应的长度),然后找出两堆子串对应的hash值中相等的那些,便可以找到最大长度,时间复杂度 O(n^2 + m^2 )

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
const LL MOD = 100000007;	//模数
const LL P = 10000019;	//P为计算hash值时的进制数
const LL MAXN = 1010;	//MAXN为字符串最长长度
//powP[i]存放p^i%MOD,H1和H2分别存放str1和str2的hash值
LL powP[MAXN],H1[MAXN]={0},H2[MAXN]={0};
//pr1存放str1的所有<子串hash值,子串长度>,pr2同理
vector >pr1,pr2;

//init函数初始化powP函数
void init(int len){
	powP[0]=1;
	for(int i=1;i<=len;i++){
		powP[i] = (powP[i-1]*P) % MOD;
	}
}

//calH函数计算字符串str的hash值
void calH(LL H[],string &str){
	H[0] = str[0];	//H[0]单独处理
	for(int i=1;i存入pr
void calSubH(LL H[],int len,vector > &pr){
	for(int i=0;i

 问题三:还是最长回文子串,这里将用字符串hash+二分解决,时间复杂度为O(nlogn)

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
const LL MOD = 100000007;	//模数
const LL P = 10000019;	//P为计算hash值时的进制数
const LL MAXN = 200010;	//MAXN为字符串最长长度
//powP[i]存放p^i%MOD,H1和H2分别存放str1和str2的hash值
LL powP[MAXN],H1[MAXN],H2[MAXN];

//init函数初始化powP函数
void init(){
	powP[0]=1;
	for(int i=1;imid
	}
	return l-1;	//返回最大回文半径
}
int main() {
	init();
	string str;
	getline(cin,str);	//计算str的hash数组
	reverse(str.begin(),str.end()); 	//将字符串反转
	calH(H2,str);	//计算rstr的hash数组
	int ans=0;
	//奇回文
	for(int i=0;i











你可能感兴趣的:(C++)