Rust 如何查找两个字符串中是否有公共字符
我是个新手,不知道这两个字符串是否有共同的字符。我知道应该有一种不使用regex(我不反对regex)的简单方法,可以使用Rust 如何查找两个字符串中是否有公共字符,rust,Rust,我是个新手,不知道这两个字符串是否有共同的字符。我知道应该有一种不使用regex(我不反对regex)的简单方法,可以使用my_str.chars().any(),但我不确定如何实现这一点 我以前在Python中通过比较集合完成过这项工作 if len(set(candidate) & set(required)) < 1: 因此,我能够使用any获得解决方案。但由于我是个新手,我不确定这是不是最好的方法。也许使用hashset会更有效?我的应用程序很小,所以效率不是一个很大的
my_str.chars().any()
,但我不确定如何实现这一点
我以前在Python中通过比较集合完成过这项工作
if len(set(candidate) & set(required)) < 1:
因此,我能够使用
any
获得解决方案。但由于我是个新手,我不确定这是不是最好的方法。也许使用hashset
会更有效?我的应用程序很小,所以效率不是一个很大的因素。最“质朴”的方式是什么?你可以通过几种方式来实现,这里有几个选项:
- 构建第一个字符串的集合,并检查第二个字符串是否包含该集合中的字符[O(n+m)]
- 遍历第一个字符串的字符,并检查第二个字符串是否包含其中任何字符[O(n*m)]
哈希集
,但如果只关心ascii(因此限制为256种可能性),则可以使用基本数组
这将比使用静态集更有效。
。任何+。包含意味着从一个字符串中为每个字符从另一个字符串中迭代所有元素(复杂性O(nm)
)
相反,您可以使用hashmap并将每个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));
}
你能不能更具体一点你想做什么,你的问题是什么?为什么要在Python代码中将长度与1进行比较?您是否尝试过将Python代码直接翻译成Rust,在这样做时是否遇到过任何问题?目前我不明白你的具体问题是什么。他想知道字符串是否有共同的字符。python代码将两个字符串转换为集合,并检查集合交集的长度是否大于0。@MadWombat我知道目标是什么。我不明白的是具体的问题。Ptyhon代码以一种相当直截了当的方式转换为Rust实现,但是OP似乎遇到了一些障碍。当然,我可以只编写代码(),但是如果我理解实际问题的话,我想我可以给出一个更有用的答案。关于Python代码,我只是想知道为什么它以<1
而不是!=0
@PitaJ在编写Python时,我通常更关心简洁性和可读性,而不是性能,但你是对的。:)您的解决方案具有时间复杂度O(mn),其中m和n分别是两个字符串的长度。使用集合的解具有O(m+n)的(摊销)复杂度,因此它渐进地快得多。对于非常短的字符串,它甚至可能会稍微慢一点。请避免只回答代码,并解释它是如何工作的,为什么它更有效?
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));
}
str1.chars().any(|c| match c {
'a' | 'd' | 'f' | 'e' => true,
_ => false,
});
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));
}