Как найти, если две строки имеют общие символы в Rust - PullRequest
0 голосов
/ 18 октября 2018

Я новичок в ржавчине и пытаюсь выяснить, имеют ли две строки общие символы.Я знаю, что должен быть простой способ сделать это без использования регулярных выражений (я не против регулярных выражений), возможно, с помощью my_str.chars().any(), но я не уверен, как это реализовать.

Я делал это раньше в Python, сравнивая наборы.

if len(set(candidate) & set(required)) < 1: 

Спасибо!

РЕДАКТИРОВАТЬ

let result = candidate.chars().any(|c| required.contains(c));

Итак, я смог найти решение для работы, используя any.Но так как я новичок в ржавчине, я не уверен, что это лучший способ.Возможно, использование HashSets будет более эффективным?Мое приложение маленькое, поэтому эффективность не имеет большого значения.Какой самый "деревенский" способ?

1 Ответ

0 голосов
/ 19 октября 2018

Вы можете подойти к нему несколькими способами, вот несколько вариантов:

  • построить набор первой строки и проверить, содержит ли вторая строка символ в этом наборе [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,
});

Это будет гораздо более производительным, чем даже при использовании статического набора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...