題目鏈結
給定乙個字串 a 和乙個字串 b,求 b 在 a 中的出現次數。
a 中不同位置出現的 b 可重疊。
input
輸入共兩行,分別是字串 a 和字串 b。
output
輸出乙個整數,表示 b 在 a 中的出現次數。
sample input
zyzyzyz
zyzsample output
3hint
1≤a,b 的長度 ≤10e6 ,a 、b 僅包含大小寫字母。
分析:
字串問題:一般有雜湊和kmp兩種做法
字串hash(雜湊):
所求的問題:求字串b在字串a**現的位置或者次數。
暴力思維
列舉字串a中個所有位置,非常浪費時間
例如字串a為aaaaaaaaaaab 字串b為aaaab
雜湊思維
例如字串a為aaaaaaaaaaab 字串b為aaaab
字串b長度=5,求出字串b的雜湊值,並且利用字首和思想求字元a的雜湊值
然後利用字首和思想可知任意一段長度的雜湊值
接下來就是尋找字串a長度為5的雜湊值且與字串b的雜湊值相等的位置,當然也可以求個數利用字首和思想求字元a的雜湊值具體思路:
假設字元a為acda,字串b為cd,這裡在假定a=1,c=3,d=4
這裡只是簡化下面的敘話,寫**過程中無需這麼寫
首先,引入乙個質數b,不要太大也不要太小
接著 定義h[0]=1,長度為i的雜湊值定義為h[i]
h(1)=1
h(2)=1*b+3
h(3)=1*b^2+3*b+4
h(4)=1*b^3+3*b^2+4*b+1
顯而易見,h[k+1]=h(k)*b+c[k+1]
這裡c為字串,m為字串的長度
同理可得b的雜湊值為s=3*b+4
我們可以發現h(3)-h(2)*(b^2)==3*b+4
很明顯,最後乘以b的幾次方是根據字串b的長度而定的
字串hash的正確性(本人並不是很理解,但這都是前人的定理)
字串hash對於任意不同的字串所產生的雜湊值必然是互不相同的嗎
顯然不是的
但如果我們的雜湊函式所生成的雜湊值是隨機分布的話,不同的字串雜湊值相等的
概率是很低的,因此我們常常認為競賽中的題目不會出現字串相等的情況,實際上
根據生日悖論,對於[0,n)內均勻分布的雜湊函式,出現不同字串雜湊值相等
的期望是o(sqrt(n)),這在選擇雜湊函式時可以作為乙個效率和正確性參考。
這裡要說明一下,這裡的雜湊函式是這樣的
其實取模的意義在於不爆資料,但是對於此題不去模也是對的,因為計算機對於爆的資料也有一定的處理規則,並不是隨意返回乙個值,所以我們便可認定對於爆了的兩個不同的數,計算機返回的值也不相同,此題我們只考慮雜湊值相不相等,而不考慮為正還是為負。
但一些題中需要用雜湊值作為下標的話,這就必須取模了
為了增強hash的正確性
可以採用「雙雜湊」來降低不同字串出現相同雜湊值的概率,即取不同的模數,把
不同模數算出的雜湊值都記下來,只有幾個雜湊值都一樣,我們才判定字串匹配。
通常用雙雜湊就可以就可以將衝突降到最低,如果分別取h=10e9+7和10e9+9,就
幾乎不可能發生衝突,因為他們是一對「孿生質數」。當然為了考慮下標,我們可以
考慮取10e6左右的質數,比如999979。
該題的**:(不取模)
#include#include#include#define maxn 1000010
#define b 31
using namespace std;
typedef long long ll;
char a[maxn],b[maxn];
ll sum[maxn];//用來存放前i位雜湊值
ll power[maxn];
void init()//儲存b^n(n=1,2,3,4,5,6...)
int main()
int main()
printf("%d\n",ans);
} }return 0;
}
php統計所有字元在字串中出現的次數
效果如圖 演算法 迴圈一次字串 本例的 str 把出現過的字串記錄在乙個陣列 如本例的 strrecord 內,如果已經此記錄函式已經有,則不記錄 在每個字串時,拿來與記錄陣列的值進行比較 本例的 strrecord key 如果記錄裡的某個值和這個字串一樣,就記錄次數 1 本例的 strrecor...
計算字串中子串出現的次數
2.計算字串中子串出現的次數利用輸入函式輸入任意兩個字串,請編寫程式求出第二個字串在第乙個字串 現的次數,即在第乙個字串中有幾個第二個字串。例1 輸入123sdk123dfg123121 123輸出 3 例2 輸入 1wdfw112sfrtes wq輸出 0 include include int ...
計算字串中字元出現的次數
description 輸出字元出現的次數,並按照字母順序表排序輸出 輸入ddkafadf 輸出a2d3f2k1 分析 ascii表中共有128個元素,其中包括了a z,我們可以初始化乙個長為128的陣列,用來表示所有元素個數都為0,然後遍歷要計算的字串,遍歷字串的內容即為初始化陣列的下標。以下面 ...