日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 3461 字符串匹配(KMP / 哈希(有推导))

發布時間:2024/7/5 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 3461 字符串匹配(KMP / 哈希(有推导)) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. 題目
      • 1.1 題目鏈接
      • 1.2 題目大意
    • 2. Accepted代碼
      • 2.1 KMP解法
      • 2.2 哈希法(有推導過程)

1. 題目

1.1 題目鏈接

http://poj.org/problem?id=3461
類似題目:LeetCode 30. 串聯所有單詞的子串(字符串哈希)

1.2 題目大意

模式串在主串中出現過幾次。

2. Accepted代碼

2.1 KMP解法

#include <stdio.h> #include <iostream> #include <cstring> int next[10001]; char a[1000001], b[10001]; void calNexts(char *b, int m, int *next) {next[0] = -1;int j = 0, k = -1;while(j < m){if(k == -1 || b[j] == b[k]){j++;k++;next[j] = k;}elsek = next[k];} } int str_kmp(char *a, int n, char *b, int m) {calNexts(b, m, next);int i = 0, j = 0, times = 0;while(i < n && j < m){if(j == -1 || a[i] == b[j]){i++;j++;}else{j = next[j];}if(j == m){times++;j = next[j];}}return times; } int main() {int count;std::cin >> count;while(count--){scanf("%s",&b);scanf("%s",&a);printf("%d\n",str_kmp(&a[0], strlen(a), &b[0], strlen(b)));}return 0; }

2.2 哈希法(有推導過程)



參考別人的哈希函數,哈希值的求法很犀利
自己推導的過程如下:

/*** @description: poj 3461 字符串匹配,哈希法* @author: michael ming* @date: 2019/6/26 21:59* @modified by: */ #include <stdio.h> #include <iostream> #include <cstring> #include <cmath> #define K 25 //K大于等于字符集數 k>=25 typedef unsigned long long ull; char a[1000001], b[10001]; ull ha[1000001]; ull powk[10001];//存儲K的冪值 using namespace std; void fillpowk(int m) {powk[0] = 1;for(int i = 1; i <= m; ++i)powk[i] = powk[i-1]*K; } ull hashf(int m, char *str) {ull value = 0;for(int i = 0; i < m; ++i)value = value * K + str[i];return value; } int str_RK(char *a, int n, char *b, int m)//a是主串,b是模式串 {fillpowk(m);int i, times = 0;ull hash_val, value = 0;value = hashf(m,b); //計算模式串的hash值valueha[0] = ull(a[0]);for(i = 1; i < n; ++i)ha[i] = ha[i-1] * K + a[i];for(i = 0; i < n-m+1; ++i)//最多n-m+1次比較{if(i == 0)hash_val = hashf(m,a);elsehash_val = ha[i+m-1] - ha[i-1]*powk[m];//這個公式可以自己推導一下if(hash_val == value){//如果子串哈希值等于模式串的,匹配成功(該哈希無沖突)times++;}}return times; } int main() {int count;std::cin >> count;while(count--){scanf("%s",&b);scanf("%s",&a);printf("%d\n",str_RK(&a[0], strlen(a), &b[0], strlen(b)));}return 0; }

總結

以上是生活随笔為你收集整理的POJ 3461 字符串匹配(KMP / 哈希(有推导))的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。