Skip to content

Commit f31b9ea

Browse files
author
Caitlin Gao
committed
feat(geektime_algo): add 32 string, BF and RK
1 parent 31b0908 commit f31b9ea

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

rust/32_string/bf_rk.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use std::collections::HashMap;
2+
3+
fn bf(primary: &str, pattern: &str) -> i32 {
4+
if primary.is_empty() || pattern.is_empty() || primary.len() < pattern.len() { return -1; }
5+
6+
let primary_chars: Vec<char> = primary.chars().collect();
7+
let pattern_chars: Vec<char> = pattern.chars().collect();
8+
for i in 0..(primary.len() - pattern.len() + 1) {
9+
if pattern_chars == primary_chars[i..i + pattern.len()].to_vec() {
10+
return i as i32;
11+
}
12+
}
13+
-1
14+
}
15+
16+
// 通过哈希算法对主串中的 n-m+1 个子串分别求哈希值,
17+
// 逐个与模式串的哈希值比较大小。如果某个子串的哈希值与模式串相等,那就说明对应的子串和模式串匹配
18+
fn rk(primary: &str, pattern: &str) -> i32 {
19+
if primary.is_empty() || pattern.is_empty() || primary.len() < pattern.len() { return -1; }
20+
21+
let primary_chars: Vec<char> = primary.chars().collect();
22+
let pattern_chars: Vec<char> = pattern.chars().collect();
23+
let base: i128 = 26;
24+
let m = pattern.len();
25+
let n = primary.len();
26+
let mut pow_vec = vec![];
27+
let mut hash = HashMap::new();
28+
29+
// 存储 26 的 n 次方到数组中,方便后面调用
30+
for i in 0..m {
31+
pow_vec.push(base.pow(i as u32));
32+
}
33+
34+
// 计算子串的 hash 值
35+
let mut p_value = 0;
36+
for i in 0..m {
37+
p_value += (pattern_chars[i] as i128 - 'a' as i128) * pow_vec[m-1-i];
38+
}
39+
40+
// 计算主串的 n-m+1 个子串的 hash 值
41+
for i in 0..(n - m + 1) {
42+
// 计算主串中 index 为 0 的子串的 hash 值
43+
let mut value = 0;
44+
if i == 0 {
45+
for i in 0..m {
46+
value += (primary_chars[i] as i128 - 'a' as i128) * pow_vec[m-1-i];
47+
}
48+
} else {
49+
// 计算 index 为 i 的子串的 hash 值
50+
// 计算公式: hash[i] = (hash[i-1] - 26^(m-1) * (primary_chars[i-1] - 'a')) * 26 + (26^0 * (primary_chars[i+m-1] - 'a'))
51+
value = (hash[&((i-1) as i32)] - base.pow((m-1) as u32) * (primary_chars[i-1] as i128 - 'a' as i128)) * base + ((primary_chars[i+m-1]) as i128 - 'a' as i128);
52+
}
53+
54+
// hash 值相等,比较两个串内容是否相等,避免 hash 碰撞
55+
if value == p_value && pattern_chars == primary_chars[i..i+m].to_vec() {
56+
return i as i32;
57+
}
58+
59+
hash.insert(i as i32, value);
60+
}
61+
62+
-1
63+
}
64+
65+
fn main() {
66+
let primary = "thequickbrownfoxjumpsoverthelazydog";
67+
let pattern = "jump";
68+
let result = bf(primary, pattern);
69+
println!("{}", result); // 16
70+
71+
let result2 = rk(primary, pattern);
72+
println!("{:?}", result2); // 16
73+
}

0 commit comments

Comments
 (0)