refactor(字符串哈希): 重构字符串哈希实现并优化代码结构

将P3370.cpp从src/2移动到src/11/28目录并重构实现
新增P3375.cpp实现字符串匹配和回文前缀查找功能
使用更简洁的代码风格和更高效的哈希算法
This commit is contained in:
Zengtudor 2025-11-28 14:05:58 +08:00
parent 4ec66e7a1e
commit 1d1598fdc2
3 changed files with 108 additions and 38 deletions

32
src/11/28/P3370.cpp Normal file
View File

@ -0,0 +1,32 @@
#include <cstdint>
#include <iostream>
#include <istream>
#include <set>
#include <string>
using ll = int64_t;
const ll b=233,p=1e9+7;
ll n;
std::string tmp;
std::set<ll> s;
static inline ll strhash(std::string &s){
ll res=0;
for(ll i=0;i<s.size();i++){
res=(res*b+s[i]-'0')%p;
}
return res;
}
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>n;
for(ll i=1;i<=n;i++){
std::cin>>tmp;
s.emplace(strhash(tmp));
}
std::cout<<s.size()<<"\n";
}

76
src/11/28/P3375.cpp Normal file
View File

@ -0,0 +1,76 @@
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <istream>
#include <string>
#include <vector>
using ll = int64_t;
#define printf
#define sl static inline
const ll b=233,p=1e9+7;
std::string s1,s2;
ll n1,n2,h2;
std::vector<ll> v1,bp,v2,v2r;
sl ll strhash(std::string&s){
ll res=0;
for(ll i=0;i<s.size();i++){
res=(res*b+s[i])%p;
}
return res;
}
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>s1>>s2;
h2=strhash(s2);
n1=s1.size(),n2=s2.size();
s1=' '+s1;s2=' '+s2;
v1.resize(s1.size());
v2.resize(s2.size());
v2r.resize(s2.size()+1);
bp.resize(std::max(s1.size(),s2.size()));
bp[0]=1;
for(ll i=1;i<bp.size();i++){
bp[i]=(bp[i-1]*b)%p;
}
for(ll i=1;i<=n1;i++){
v1[i]=(v1[i-1]*b+s1[i])%p;
if(ll s=i-n2+1;s>=1){
ll h1=(v1[i]-v1[s-1]*bp[n2]%p+p)%p;
printf("v1=%lld, h1=%lld, h2=%lld\n",v1[i],h1,h2);
if(h1==h2){
std::cout<<s<<"\n";
}
}
}
for(ll i=1;i<=n2;i++){
v2[i]=(v2[i-1]*b+s2[i])%p;
}
for(ll i=n2;i>=1;i--){
v2r[i]=(v2r[i+1]*b+s2[i])%p;
}
for(ll i=1;i<=n2;i++){
ll l=1,r=i/2,ans=0,mid;
while(l<=r){
mid=(l+r)/2;
ll h1=v2[mid];
// ll h2=(v2[i]-v2[i-mid]*bp[mid]%p+p)%p;
ll h2=(v2r[i-mid+1]-v2r[i+1]*bp[mid]%p+p)%p;
printf("i=%lld, l=%lld, r=%lld, mid=%lld, h1=%lld, h2=%lld\n",i,l,r,mid,h1,h2);
if(h1==h2){
ans=mid;
l=mid+1;
}else{
r=mid-1;
}
}
std::cout<<ans<<" ";
}
std::cout<<"\n";
}

View File

@ -1,38 +0,0 @@
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <istream>
using namespace std;
using ull= unsigned long long;
ull base = 131;
ull a[10010];
char s[10010];
int n, ans = 1;
int prime = 233317;
const ull mod = 212370440130137957ll;
ull mhash(char *s) {
int len = strlen(s);
ull ans = 0;
for (int i = 0; i < len; i++)
ans = (ans * base + (ull)s[i]) % mod + prime;
return ans;
}
int main() {
iostream::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s;
a[i] = mhash(s);
}
sort(a + 1, a + n + 1);
for (int i = 1; i < n; i++) {
if (a[i] != a[i + 1])
ans++;
}
cout << ans << '\n';
}