1. 程式人生 > 其它 >idea建立一個乾淨的SpringMVC專案

idea建立一個乾淨的SpringMVC專案

字串雜湊

雜湊基本思想就是兩個物件的對映,字串雜湊則是將一個字串對映到一個數上,用這個數即可代表這個字串,而這個數被稱為雜湊值

那麼如何計算雜湊值呢?

我們知道字串的每個字元其實相等於一個數字,因此我們可以把每個字串看成一個整數,之後將其轉化為P進位制下mod一個質數的數字,而這個數也就是這個字串的雜湊值。

例:"ABCD" -----> \((A\times P^3+B\times P^2+C\times P^1+D\times P^0) \,mod \,K\)

一般我們取P為131 或 13331, Q 為 \(2^{64}\)可以保證大部分情況下不出現雜湊衝突

而mod Q 的操作我們可以通過將變數定義為unsigned long long來省略,因為在ull下當數值溢位範圍後會自動對\(2^{64}\)

取模

雜湊字首

我們定義h[i] 表示字串第1個到第i個字元組成的子串的雜湊值

那如何求l到r的子串雜湊值呢?

結論:res = h[r] - h[l - 1] * p[r - l + 1]

**我們不能直接向前綴和那樣h[r] - h[l - 1], 因為此時在h[r]中1 - l-1的雜湊值與h[l - 1]並不相同,而差的值正好就是他們直接相差的位數,因此乘上\(p^{r-l+1}\)即可,這裡我們已經預處理p[i]來表示\(p^i\)了 **

通過這樣的方法在預處理後我們可以用\(O(1)\)的複雜度獲得一段字元的雜湊值,並利用雜湊值高效完成一系列其他操作

例:841. 字串雜湊 - AcWing題庫

程式碼示例:

//#pragma comment(linker,   "/STACK:10240000000000,10240000000000")
//#pragma GCC optimize(2)

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for (int i=(a);i<=(b);++i)
#define per(i,b,a) for (int i=(b);i>=(a);--i)
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define itt iterator
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#define lowbit(x) x & (-x)
#define clr(x) memset(x, 0, sizeof(x));
#define fi first
#define se second
#define mp make_pair
#define MOD 1000000007
typedef vector<int> vii;
typedef vector<long long> vll;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef set<int> si;
typedef set<ll> sll;
ll ksm(ll a, ll b, ll p) {if (b == 0) return 1; ll ns = ksm(a, b >> 1, p); ns = ns * ns % p; if (b & 1) ns = ns * a % p; return ns;}		
const int MAXN = 0x7fffffff;

const int N = 1e5 + 5, P = 131;

ull p[N];
ull h[N];
int n, m;	
char str[N];

ull get(int l, int r)
{
	return h[r] - h[l - 1] * p[r - l + 1];
}

int main ()
{	
	//IOS;
	cin >> n >> m;
	cin >> str + 1;
	p[0] = 1;
	for(int i = 1; i <= n; i ++)
	{
		p[i] = p[i - 1] * P; //預處理p陣列
		h[i] = h[i - 1] * P + str[i];//預處理雜湊字首陣列
	}
	while(m --)
	{
		int l1, r1, l2, r2;
		cin >> l1 >> r1 >> l2 >> r2;
		if(get(l1, r1) == get(l2, r2)) puts("Yes");
		else puts("No");
	}
	return 0;
}	
/*

*/