算法模板-字符串

字符串

trie树和01trie树

这部分内容可以参见之前的blog

字符串哈希

cpp 复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

// 使用 unsigned long long 自然溢出通常比手写 mod 快且安全
// 如果怕被卡,可以保留你的大质数 mod
typedef unsigned long long ull;

const int N = 10010;
const ull base = 131;
const ull prime = 233317;

ull a[N];
char s[N];
int n;

// 统一后的 Hash 函数逻辑
ull get_hash(char str[]) {
    ull res = 0;
    int len = strlen(str);
    for (int i = 0; i < len; i++) {
        // 按照你习惯的迭代式写法
        res = res * base + (ull)str[i] + prime;
    }
    return res;
}

int main() {
    // 保持你 scanf/printf 的简洁性
    if (scanf("%d", &n) == EOF) return 0;

    for (int i = 1; i <= n; i++) {
        scanf("%s", s);
        a[i] = get_hash(s);
    }

    // 排序后去重计数
    sort(a + 1, a + n + 1);

    int ans = 1;
    for (int i = 1; i < n; i++) {
        if (a[i] != a[i + 1]) ans++;
    }

    // 处理 n=0 的特殊情况(虽然题目通常 n>=1)
    if (n == 0) printf("0\n");
    else printf("%d\n", ans);

    return 0;
}

KMP

cpp 复制代码
#include<iostream>
 
using namespace std;
 
const int N = 100010, M = 1000010;
 
int n, m;
char p[N], s[M];
int ne[N];
 
int main()
{
    cin >> n >> p + 1 >> m >> s + 1;
    
    //next数组的实现
    //从二开始 因为next[1] = 0
    for(int i = 2, j = 0; i <= n; i++)
    {
        while(j && p[i] != p[j + 1]) j = ne[j]; //匹配失败回到最大重复的地方
        if(p[i] == p[j + 1]) j++;
        ne[i] = j; //将当前子字符串p[0到i]的最长重复前后缀长度赋给ne[i]
    }
    
    //KMP匹配过程
    for(int i = 1, j = 0; i <= m; i++)
    {
        while(j && s[i] != p[j + 1]) j = ne[j]; 
        //如果不匹配就移动最小距离到最长重复前后缀的地方重新匹配
        //或者j==0时字符串s与模式串p开头就不一样 s就向后走
        if(s[i] == p[j + 1]) j++;
        if(j == n)
        {
            cout << i - n << " ";
            j = ne[j]; //匹配成功后返回到最小移动 也就是最大重复的前后缀的地方再检验是否还有匹配的
        }
    }
    
    return 0;
}

Manacher算法

cpp 复制代码
//模板
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int N=1.2e7+10;
int p[2*N];
char s1[2*N];
int main(){
    string s;
    cin>>s;
    for (int i=0;i<s.length();i++){
        s1[2*i+1]=s[i];
        s1[2*i]='#';
    }
    s1[2*s.length()]='#';
    s=s1;
    int c=0;
    int r=0;
    int maxlen=1;
    for (int i=0;i<s.length();i++){
        p[i]=i<r?min(p[2*c-i],r-i):1;
        while (i-p[i]>=0&&s[i-p[i]]==s[i+p[i]])
            ++p[i];
        if (i+p[i]>r){
            c=i;
            r=i+p[i];
        }
        maxlen=max(maxlen,2*p[i]-1);
    }  
    cout<<maxlen/2<<endl;
    return 0;
}
相关推荐
UIU1147 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场8 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi8 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
秋天的怀念_David9 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院10 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng10 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
叉烧滑蛋12 小时前
B站台湾大学郭彦甫|MATLAB 学习笔记|04 变量与档案存取
数据结构
j7~13 小时前
【穷举、深搜与回溯算法】一棵决策树讲透全排列与子集
数据结构·c++·算法·leetcode·回溯·递归
傅科摆 _ py14 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法
Shaoshing14 小时前
LeetCode100 42.接雨水
java·算法·leetcode