mirror of
https://github.com/ZhuJHua/moodiary.git
synced 2026-04-05 16:31:45 +08:00
fix(rust): fix string error in kmp
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
use flutter_rust_bridge::frb;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn build_prefix_table(pattern: &str) -> Vec<usize> {
|
||||
pub fn build_prefix_table(pattern: &[char]) -> Vec<usize> {
|
||||
let m = pattern.len();
|
||||
let mut prefix_table = vec![0; m];
|
||||
let mut j = 0;
|
||||
|
||||
for i in 1..m {
|
||||
while j > 0 && pattern.chars().nth(i) != pattern.chars().nth(j) {
|
||||
while j > 0 && pattern[i] != pattern[j] {
|
||||
j = prefix_table[j - 1];
|
||||
}
|
||||
if pattern.chars().nth(i) == pattern.chars().nth(j) {
|
||||
if pattern[i] == pattern[j] {
|
||||
j += 1;
|
||||
}
|
||||
prefix_table[i] = j;
|
||||
@@ -20,16 +20,18 @@ pub fn build_prefix_table(pattern: &str) -> Vec<usize> {
|
||||
}
|
||||
|
||||
pub fn kmp_search(text: &str, pattern: &str) -> Vec<usize> {
|
||||
let m = pattern.len();
|
||||
let prefix_table = build_prefix_table(pattern);
|
||||
let text_chars: Vec<char> = text.chars().collect();
|
||||
let pattern_chars: Vec<char> = pattern.chars().collect();
|
||||
let m = pattern_chars.len();
|
||||
let prefix_table = build_prefix_table(&pattern_chars);
|
||||
let mut matches = Vec::new();
|
||||
let mut j = 0;
|
||||
|
||||
for (i, c) in text.chars().enumerate() {
|
||||
while j > 0 && Some(c) != pattern.chars().nth(j) {
|
||||
for (i, &c) in text_chars.iter().enumerate() {
|
||||
while j > 0 && c != pattern_chars[j] {
|
||||
j = prefix_table[j - 1];
|
||||
}
|
||||
if Some(c) == pattern.chars().nth(j) {
|
||||
if c == pattern_chars[j] {
|
||||
j += 1;
|
||||
}
|
||||
if j == m {
|
||||
@@ -58,7 +60,6 @@ impl Kmp {
|
||||
if !match_entries.contains_key(&index)
|
||||
|| match_entries[&index].0.len() < pattern.len()
|
||||
{
|
||||
// 确保在相同索引位置,优先使用较长的模式
|
||||
match_entries.insert(index, (pattern, replacement));
|
||||
}
|
||||
}
|
||||
@@ -66,15 +67,21 @@ impl Kmp {
|
||||
|
||||
let mut result = String::new();
|
||||
let mut last_index = 0;
|
||||
|
||||
let mut match_entries: Vec<_> = match_entries.into_iter().collect();
|
||||
match_entries.sort_by_key(|&(index, _)| index);
|
||||
|
||||
let text_chars: Vec<char> = text.chars().collect();
|
||||
for (index, (pattern, replacement)) in match_entries {
|
||||
if index >= last_index {
|
||||
result.push_str(&text[last_index..index]);
|
||||
let start_byte_index = text_chars[..index]
|
||||
.iter()
|
||||
.map(|c| c.len_utf8())
|
||||
.sum::<usize>();
|
||||
let end_byte_index = start_byte_index + pattern.len();
|
||||
|
||||
if start_byte_index >= last_index {
|
||||
result.push_str(&text[last_index..start_byte_index]);
|
||||
result.push_str(replacement);
|
||||
last_index = index + pattern.len();
|
||||
last_index = end_byte_index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ fn wire__crate__api__kmp__build_prefix_table_impl(
|
||||
};
|
||||
let mut deserializer =
|
||||
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
||||
let api_pattern = <String>::sse_decode(&mut deserializer);
|
||||
let api_pattern = <Vec<char>>::sse_decode(&mut deserializer);
|
||||
deserializer.end();
|
||||
move |context| {
|
||||
transform_result_sse::<_, ()>((move || {
|
||||
@@ -340,6 +340,14 @@ impl SseDecode for Kmp {
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for char {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
let mut inner = <String>::sse_decode(deserializer);
|
||||
return inner.chars().next().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for std::collections::HashMap<String, String> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
@@ -404,6 +412,18 @@ impl SseDecode for i32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for Vec<char> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
let mut len_ = <i32>::sse_decode(deserializer);
|
||||
let mut ans_ = vec![];
|
||||
for idx_ in 0..len_ {
|
||||
ans_.push(<char>::sse_decode(deserializer));
|
||||
}
|
||||
return ans_;
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for Vec<String> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
@@ -644,6 +664,13 @@ impl SseEncode for Kmp {
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for char {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
<String>::sse_encode(self.to_string(), serializer);
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for std::collections::HashMap<String, String> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
@@ -713,6 +740,16 @@ impl SseEncode for i32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for Vec<char> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
<i32>::sse_encode(self.len() as _, serializer);
|
||||
for item in self {
|
||||
<char>::sse_encode(item, serializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for Vec<String> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
|
||||
Reference in New Issue
Block a user