Rust 如何查找两个字符串中是否有公共字符

Rust 如何查找两个字符串中是否有公共字符,rust,Rust,我是个新手,不知道这两个字符串是否有共同的字符。我知道应该有一种不使用regex(我不反对regex)的简单方法,可以使用my_str.chars().any(),但我不确定如何实现这一点 我以前在Python中通过比较集合完成过这项工作 if len(set(candidate) & set(required)) < 1: 因此,我能够使用any获得解决方案。但由于我是个新手,我不确定这是不是最好的方法。也许使用hashset会更有效?我的应用程序很小,所以效率不是一个很大的

我是个新手,不知道这两个字符串是否有共同的字符。我知道应该有一种不使用regex(我不反对regex)的简单方法,可以使用
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存储为键,将boolint存储为值:
在这种情况下,您将在第一次迭代中存储第一个字符串中的所有字符,然后迭代第二个字符串,尝试从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));
}