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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

POJ 1200 Crazy Search 查找有多少种不同的子串(hash)

發布時間:2024/7/5 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 1200 Crazy Search 查找有多少种不同的子串(hash) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1.采用map解題
    • 2.采用hash查找

題目鏈接: http://poj.org/problem?id=1200
題目大意:給定子串長度,字符中不同字符數量,以及一個字符串,求不同的子串數量。

1.采用map解題

把子串插入map,map自動去重,最后輸出map的size
結果是超時的。

超時代碼:

/*** @description: http://poj.org/problem?id=1200,采用map解題* @author: michael ming* @date: 2019/5/8 16:14* @modified by: */ #include <iostream> #include <stdio.h> #include <map> #include <string> using namespace std; int main() {size_t sublen, diffchar;scanf("%d%d",&sublen,&diffchar);map<string, int> substring;string str, substr;cin >> str;size_t len = str.size();for(size_t i = 0, j = i+sublen-1; j < len; i++,j++){substr = str.substr(i, sublen);substring.insert(pair<string, int>(substr, 1));}cout << substring.size();return 0; }

2.采用hash查找

  • 先將字符串中先后出現的字符映射成1,2,3,4…比如abac(1213)
  • 在將每個子串對應的sublen個字符哈希得到哈希值,因為題目說可能的子串組合小于1600萬種,我們把得到的哈希值對1600萬求模,存在數組中置為1(初始為0)。
  • 對后面的子串的哈希值在數組中檢查,如果為0,則不存在,種類+1,如果為1,說明這種子串已存在,跳過,循環遍歷字符串
  • hash可以實現O(1)時間復雜度查找,所以時間比較短。
  • 該題目情況下,所有子串要求的長度是一樣的,用類似m進制數的哈希函數沒有沖突,如果子串長度不要求一樣,則以下求解方法存在沖突可能(一個很長的子串哈希完的哈希int值溢出了,即高位舍棄變成很小的數,這可能與短字符串的哈希值一樣,造成沖突)。

    AC代碼:
/*** @description: 計算子串的種數* @author: michael ming* @date: 2019/5/8 17:20* @modified by: */ #include <iostream> #include <string> #include <memory.h> using namespace std; void chartoint(string &str, int *num) //把字符中出現過的字符轉成1開始的數字 {int value = 1;int len = str.size();for(int i = 0; i < len; ++i){if(num[str[i]] == 0)num[str[i]] = value++;} } size_t hashfunc(int i, int j, int m, int *num, string &str) //計算子串hash值 {int hashValue = 0;for(int k = i; k <= j; ++k)hashValue = hashValue*m + num[str[k]];return hashValue; } int main() {const unsigned int max = 16000001;int num[300] = {0};size_t *hash = new size_t[max];memset(hash, 0, sizeof(hash));int sublen, m;int result = 0;string str;cin >> sublen >> m >> str;chartoint(str, num);for(int i = 0; i <= str.size()-sublen; ++i){size_t hashValue = hashfunc(i, i+sublen-1, m, num, str)%max;if(!hash[hashValue]){result++;hash[hashValue] = 1;}}cout << result << endl;delete[] hash;return 0; }

總結

以上是生活随笔為你收集整理的POJ 1200 Crazy Search 查找有多少种不同的子串(hash)的全部內容,希望文章能夠幫你解決所遇到的問題。

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