Rust:迭代 ASCII 字符串字符的最有效方法

Ant*_*REL 1 rust

我原来的做法:

pub fn find_the_difference(s: String, t: String) -> char {
        let mut c:u8 = 0;
        for i in 0..s.chars().count() {
            c ^= t.chars().nth(i).unwrap() as u8 ^ s.chars().nth(i).unwrap() as u8;
        }
        return (c ^ t.chars().nth(s.chars().count()).unwrap() as u8) as char;
        
    }
Run Code Online (Sandbox Code Playgroud)

但它太慢了,而且我必须编写替换的所有内容都非常疯狂t[i] ^ s[i](请参阅下面的原始 C++ 函数)。所以我寻找其他东西,发现了这个方法,我们将字符串转换为字符数组,并得到了一些好的结果(从 8 毫秒到 0 毫秒)。

pub fn find_the_difference(s1: String, t1: String) -> char {
        let mut c:u8 = 0;
        let s: Vec<char> = s1.chars().collect();
        let t: Vec<char> = t1.chars().collect();

        for i in 0..s1.chars().count() {
            c ^= t[i] as u8 ^ s[i] as u8;
        }
        return (c ^ t[s1.chars().count()] as u8) as char;

    }
Run Code Online (Sandbox Code Playgroud)

但也许不需要收集,我也不关心索引,我只想一个接一个地迭代。我目前的尝试:

pub fn find_the_difference(s1: String, t1: String) -> char {
        let mut c:u8 = 0;
        let mut s = s1.chars();
        let mut t = t1.chars();
        let n = s.count();
        
        for i in 0..n {
            c ^= t.next().unwrap() as u8 ^ s.next().unwrap() as u8; // c ^= *t++ ^ *s++ translated in C++
        }
        return (c ^ t.next().unwrap() as u8) as char;
        
    }
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

Line 9, Char 44: borrow of moved value: `s` (solution.rs)
   |
4  |         let mut s = s1.chars();
   |             ----- move occurs because `s` has type `std::str::Chars<'_>`, which does not implement the `Copy` trait
5  |         let mut t = t1.chars();
6  |         let n = s.count();
   |                 - value moved here
...
9 |             c ^= t.next().unwrap() as u8 ^ s.next().unwrap() as u8;
   |                                            ^ value borrowed here after move
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)

这样的代码可以实现吗c = *t++

注意: s1.chars.count() = t1.chars.count() - 1 目标是找到 t1 中多余的字母

NB2:原始C++函数:

Line 9, Char 44: borrow of moved value: `s` (solution.rs)
   |
4  |         let mut s = s1.chars();
   |             ----- move occurs because `s` has type `std::str::Chars<'_>`, which does not implement the `Copy` trait
5  |         let mut t = t1.chars();
6  |         let n = s.count();
   |                 - value moved here
...
9 |             c ^= t.next().unwrap() as u8 ^ s.next().unwrap() as u8;
   |                                            ^ value borrowed here after move
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)

Nov*_*zen 6

我认为您对 C 和 Rust 字符串处理之间的差异以及 Rust 的strString&[u8]charu8类型之间的区别感到困惑。

也就是说,这是我实现您的功能的方式:

fn find_the_difference(s: &[u8], t: &[u8]) -> u8 {
    assert!(t.len() > s.len());
    let mut c: u8 = 0;
    for i in 0..s.len() {
        c ^= s[i] ^ t[i];
    }
    c ^ t[s.len()]
}
Run Code Online (Sandbox Code Playgroud)

如果您的数据当前是String,您可以&[u8]使用该方法查看它as_bytes()。像这样:

let s: String = ...some string...;
let t: String = ...some string...;

let diff = find_the_difference(s.as_bytes(), t.as_bytes());
Run Code Online (Sandbox Code Playgroud)