AcWing 5220. 搜索字符串
原题链接
中等
作者:
qianyezi
,
2024-10-09 16:53:08
,
所有人可见
,
阅读 3
字符串哈希+定长滑动窗口
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashSet;
public class Main {
static final int P = 131;
static long[] h = new long[(int) 2e5 + 10]; //存哈希值
static long[] p = new long[(int) 2e5 + 10]; //存P的i次幂
static String H;
static void init(int len) { //预处理哈希值
p[0] = 1;
h[0] = 0;
for (int i = 1; i < len; ++i) {
p[i] = P * p[i - 1];
h[i] = (h[i - 1] * P + H.charAt(i)) % (Long.MAX_VALUE);
}
}
static long calc(int l, int r) { //计算区间哈希值
return h[r] - h[l - 1] * p[r - l + 1];
}
static void solve() throws IOException {
String N = " " + br.readLine();
H = " " + br.readLine();
int n = N.length() - 1;
int m = H.length() - 1;
init(H.length());
HashSet<Long> set = new HashSet<>();
int[] cnt = new int[30];
for (int i = 1; i <= n; ++i) {
cnt[N.charAt(i) - 'a']++;
}
int t = 0;
for (int i = 0; i < 26; ++i) {
if (cnt[i] == 0) {
t++;
}
}
for (int i = 1; i <= m; ++i) {
int x = H.charAt(i) - 'a';
cnt[x]--;
if (cnt[x] == 0) {
t++;
} else if (cnt[x] == -1) {
t--;
}
if (i > n) {
int s = H.charAt(i - n) - 'a';
cnt[s]++;
if (cnt[s] == 0) {
t++;
} else if (cnt[s] == 1) {
t--;
}
}
if (t == 26) {
set.add(calc(i - n + 1, i));
}
}
pw.print(set.size());
}
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int t = 1;
while (t-- > 0) {
solve();
}
pw.close();
}
}