Вы можете подойти к нему несколькими способами, вот несколько вариантов:
- построить набор первой строки и проверить, содержит ли вторая строка символ в этом наборе [O (n +)m)]
- переберите символы первой строки и проверьте, содержит ли вторая строка какой-либо из них [O (n * m)]
Я решил использовать HashSet
но вы можете использовать базовый массив, если вы заботитесь только об ascii (таким образом, ограничено 256 возможностями).
use std::collections::HashSet;
fn share_char(a: &str, b: &str) -> bool {
// get which one is shorter
let (shorter, longer) = if a.len() > b.len() {
(b, a)
} else {
(a, b)
};
// fill the set with the characters from the shorter string
let set: HashSet<char> = shorter.chars().collect();
longer.chars().any(|c| set.contains(&c))
}
#[test]
fn test() {
let str1 = "abcdef";
let str2 = "the quick brown fox";
let str3 = "hijk";
assert!(share_char(str1, str2));
assert!(!share_char(str1, str3));
}
https://play.rust -lang.org /? version = stable & mode = debug & edition = 2015 & gist= 76567b94d3bd15b37e33acb9a8d701d5
Правка: изменено для использования сбора
Правка2: я хочу объяснить, почему я проверил более короткую / длинную проверку и почему я не просто построил два набора.
Вставка в HashSet
является более дорогой операцией, чем просто перебор символов строки.Это означает, что есть разница между созданием набора из длинной строки и короткой строки.Скорее всего, это различие незначительно, так как ваши строки, вероятно, будут одинаковой длины.
Эта разница в расходах также является причиной того, что я не строю второй сет.Мы не только экономим на стоимости вставки, но также можем сохранять некоторые итерации, поскольку наш any
будет закорачиваться, если найдет совпадение.
Edit3: Другое дело.Если вы просто хотите проверить, содержит ли строка какой-либо из заданного набора символов, вам следует использовать сопоставление с образцом.
str1.chars().any(|c| match c {
'a' | 'd' | 'f' | 'e' => true,
_ => false,
});
Это будет гораздо более производительным, чем даже при использовании статического набора.