我是rust的新手,他试图找出两个字符串是否共享任何公共字符。我知道应该有一种不使用正则表达式的简单方法(我不反对正则表达式),也许可以通过使用my_str.chars().any()
来实现,但是我不确定如何实现。
我以前在Python中通过比较集合来做到这一点。
if len(set(candidate) & set(required)) < 1:
谢谢!
编辑
let result = candidate.chars().any(|c| required.contains(c));
因此,我能够找到使用any
的解决方案。但是由于我不熟悉生锈,所以我不确定这是否是最好的方法。也许使用HashSets
会更有效率?我的应用程序很小,因此效率不是一个很大的因素。最“乡村”的方式是什么?
答案 0 :(得分:1)
您可以通过几种方式来实现它,这里有几个选择:
我决定使用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));
}
编辑:更改为使用收集
Edit2:我想解释一下为什么我进行了较短/较长的检查,以及为什么我不仅仅建造了两套。
插入HashSet
的操作比仅遍历字符串的字符要昂贵得多。这意味着从长字符串构建集合与从短字符串构建集合之间存在差异。由于您的字符串长度可能相似,因此这种差异可以忽略不计。
这种费用差异也是为什么我不建造第二套的原因。我们不仅节省了插入成本,而且还节省了一些迭代,因为any
如果找到匹配项就会短路。
Edit3:另一件事。如果只想检查字符串是否包含给定的一组字符,则应使用模式匹配。
str1.chars().any(|c| match c {
'a' | 'd' | 'f' | 'e' => true,
_ => false,
});
与使用静态Set相比,这将具有更高的性能。
答案 1 :(得分:0)
.any + .contains
表示将一个字符串中的所有元素迭代为另一个字符串中的每个字符(复杂度O(nm)
);
相反,您可以使用哈希图并将每个 char 作为键存储,将 bool 或 int 作为值存储:
在这种情况下,您将在第一次迭代中存储第一个字符串中的所有字符,然后迭代第二个字符串,尝试从hashmap中获取每个字符。
如果存在char,则立即返回true
(最复杂的情况是O(n+m)
)。
出于性能方面的考虑,我建议在可能的情况下使用键而不是HashMap作为索引。
fn common_chars(s1: &str, s2: &str) -> bool {
const ALPHABET_LEN: usize = 26;
const CHAR_CODE: usize = 97; // a-97, z-122
let mut alpahbet = [0; ALPHABET_LEN];
for c in s1.chars() {
alpahbet[c as usize - CHAR_CODE] += 1; // store each char from first string
}
for c in s2.chars() {
if alpahbet[c as usize - CHAR_CODE] != 0 { // a stored char is found!
return true;
}
}
false
}
#[test]
fn test() {
let str1 = "abcdef";
let str2 = "the quick brown fox";
let str3 = "hijk";
assert!(common_chars(str1, str2));
assert!(!common_chars(str1, str3));
}