#string #algorithm #rust
Вопрос:
Под сочленением я имею в виду:
let substring = "CNC";
И струна:
let s = "CNCNC";
В моей версии «соединено» означало бы, что 2
такие подстроки присутствуют.
Каков наилучший способ сделать это Rust
? Я могу придумать несколько, но тогда это в основном уродливо C
.
У меня есть что-то вроде этого:
fn find_a_string(s: amp;String, sub_string: amp;String) -> u32 {
s.matches(sub_string).count() as u32
}
Но это возвращается 1
, потому matches()
что находит только разрозненные substrings
.
Как лучше всего это сделать в Rust?
Комментарии:
1. docs.rs/memchr/2.4.1/memchr/memmem/fn.find_iter.html
2. таким образом, я не знаю результата для вашего случая
Ответ №1:
Вероятно, есть лучший алгоритм. Здесь я просто перемещаю окно с размером подстроки, которую мы ищем, поверх входной строки и сравниваю, совпадает ли это окно с подстрокой.
fn main() {
let string = "aaaa";
let substring = "aa";
let substrings = string
.as_bytes()
.windows(substring.len())
.filter(|amp;w| w == substring.as_bytes())
.count();
println!("{}", substrings);
}
Ответ №2:
Метод перебора всех окон вполне пригоден, когда ваша иголка/стог сена невелики. И действительно, это может быть даже предпочтительным решением для небольших иголок/стогов сена, поскольку теоретически оптимальное решение намного сложнее. Но по мере увеличения длины он может становиться все медленнее.
В то время как Aho-Corasick более известен своей поддержкой одновременного поиска нескольких шаблонов, его можно использовать с одним шаблоном для поиска совпадений в линейном времени. (В данном случае это очень похоже на Кнута-Морриса-Пратта.)
aho-corasick
Ящик может это сделать:
use aho_corasick::AhoCorasick;
fn main() {
let haystack = "CNCNC";
let needle = "CNC";
let matcher = AhoCorasick::new(amp;[needle]);
for m in matcher.find_overlapping_iter(haystack) {
let (s, e) = (m.start(), m.end());
println!("({:?}, {:?}): {:?}", s, e, amp;haystack[s..e]);
}
}
Выход:
(0, 3): "CNC"
(2, 5): "CNC"
Игровая площадка: https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=ab6c547b1700bbbc4a29a99adcaceabe