从0开始学算法——第十三天(Rabin-Karp 算法练习)

写在开头的话

学习了今天的基础知识,让我们来做几道题来练练手吧。(题目是别的地方扒来的,参考答案是我自己写的,肯定不是最优解,有更好的方法欢迎评论区交流)

第一题------字符串哈希匹配字符串(模板题)

第二题------字符串哈希匹配字符串(模板题)

参考答案

第一题参考答案(Python版)

python 复制代码
import sys

def solve():
    input = sys.stdin.readline
    
    n, q = map(int, input().split())
    s = input().strip()
    
    # 使用双哈希来减少冲突概率
    MOD1 = 10**9 + 7
    MOD2 = 10**9 + 9
    base = 131  # 选择一个质数作为基数
    
    # 计算前缀哈希值
    h1 = [0] * (n + 1)
    h2 = [0] * (n + 1)
    pow1 = [1] * (n + 1)
    pow2 = [1] * (n + 1)
    
    for i in range(1, n + 1):
        # 将字符映射为数字,从1开始
        val = ord(s[i-1]) - ord('a') + 1
        
        h1[i] = (h1[i-1] * base + val) % MOD1
        h2[i] = (h2[i-1] * base + val) % MOD2
        
        pow1[i] = (pow1[i-1] * base) % MOD1
        pow2[i] = (pow2[i-1] * base) % MOD2
    
    # 计算子串哈希值的函数
    def get_hash(l, r):
        # 子串 s[l:r] 的哈希值,这里使用闭区间 [l, r]
        hash1 = (h1[r] - h1[l-1] * pow1[r-l+1]) % MOD1
        hash2 = (h2[r] - h2[l-1] * pow2[r-l+1]) % MOD2
        
        # 确保结果为非负数
        if hash1 < 0:
            hash1 += MOD1
        if hash2 < 0:
            hash2 += MOD2
            
        return hash1, hash2
    
    # 处理查询
    results = []
    for _ in range(q):
        l1, r1, l2, r2 = map(int, input().split())
        
        # 获取两个子串的哈希值
        hash1_a, hash2_a = get_hash(l1, r1)
        hash1_b, hash2_b = get_hash(l2, r2)
        
        # 如果双哈希值都相等,则认为字符串相同
        if hash1_a == hash1_b and hash2_a == hash2_b:
            results.append("Yes")
        else:
            results.append("No")
    
    sys.stdout.write("\n".join(results))

if __name__ == "__main__":
    solve()

第二题参考答案(Python版)

python 复制代码
import sys

def main():
    input = sys.stdin.read
    data = input().split()
    
    n, q = int(data[0]), int(data[1])
    s = data[2]
    
    # 选择两个不同的基数和模数
    base1 = 131
    base2 = 137
    mod1 = 10**9 + 7
    mod2 = 10**9 + 9
    
    # 预处理幂值
    pow1 = [1] * (n + 1)
    pow2 = [1] * (n + 1)
    for i in range(1, n + 1):
        pow1[i] = (pow1[i-1] * base1) % mod1
        pow2[i] = (pow2[i-1] * base2) % mod2
    
    # 计算前缀哈希值
    hash1 = [0] * (n + 1)
    hash2 = [0] * (n + 1)
    
    for i in range(1, n + 1):
        c = ord(s[i-1]) - ord('a') + 1
        hash1[i] = (hash1[i-1] * base1 + c) % mod1
        hash2[i] = (hash2[i-1] * base2 + c) % mod2
    
    # 计算子串哈希值的函数
    def get_hash(l, r):
        # 计算第一个哈希值
        h1 = (hash1[r] - hash1[l-1] * pow1[r-l+1]) % mod1
        if h1 < 0:
            h1 += mod1
        
        # 计算第二个哈希值
        h2 = (hash2[r] - hash2[l-1] * pow2[r-l+1]) % mod2
        if h2 < 0:
            h2 += mod2
        
        return (h1, h2)
    
    results = []
    idx = 3
    for _ in range(q):
        l1, r1, l2, r2 = int(data[idx]), int(data[idx+1]), int(data[idx+2]), int(data[idx+3])
        idx += 4
        
        hash_l1_r1 = get_hash(l1, r1)
        hash_l2_r2 = get_hash(l2, r2)
        
        if hash_l1_r1 == hash_l2_r2:
            results.append("Yes")
        else:
            results.append("No")
    
    sys.stdout.write("\n".join(results))

if __name__ == "__main__":
    main()
相关推荐
漂流瓶jz1 小时前
UVA-11491 奖品的价值 题解答案代码 算法竞赛入门经典第二版
c++·算法·图论·题解·aoapc·算法竞赛入门经典·uva
weixin_307779135 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
海绵宝宝转agent9 小时前
learn-claude-code第1-5章开源学习笔记分享
人工智能·笔记·python·学习
每天都要写算法(努力版)9 小时前
【行业前沿报告】DAgger:让智能体在自己走到的状态上学习
人工智能·学习·机器学习
hetao173383710 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
Zootopia62611 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
longlongzihan11 小时前
从LeetCode 70. 爬楼梯看动态规划:如何精准推导状态转移方程?
c++·算法·leetcode·动态规划
91刘仁德12 小时前
HTTP协议详解:从URL到HTTP服务器的完整实战
服务器·网络·笔记·网络协议·http
2601_9603563812 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
h_a_o777oah13 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分