从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()
相关推荐
默默开发32 分钟前
完整版:本地电脑 + WiFi 搭建 AI 自动炒股 + 自我学习系统
人工智能·学习·电脑
for_ever_love__34 分钟前
Objective-C学习 NSSet 和 NSMutableSet 功能详解
开发语言·学习·ios·objective-c
仰泳的熊猫4 小时前
题目2570:蓝桥杯2020年第十一届省赛真题-成绩分析
数据结构·c++·算法·蓝桥杯
无极低码7 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发7 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
superior tigre8 小时前
22 括号生成
算法·深度优先
盐水冰9 小时前
【烘焙坊项目】后端搭建(12) - 订单状态定时处理,来单提醒和顾客催单
java·后端·学习
Hello小赵9 小时前
视频压缩编码学习(一)—— 基础知识大集合
学习
左左右右左右摇晃9 小时前
计算机网络笔记整理
笔记·计算机网络