rust 如何使用.as_bytes()反转字符串?

t3psigkw  于 2023-01-09  发布在  其他
关注(0)|答案(3)|浏览(113)

我正在尝试反转一个字符串,我使用this post的解决方案,它可以工作,但是我想尝试使用字节而不是字素簇,如下所示:

fn reverse2(input: &str) -> String {
    input.as_bytes().iter().rev().collect()
}

不幸的是,我不能在rev()之后运行函数collect(),我不知道该用哪种方法,你会怎么做?

0vvn1miw

0vvn1miw1#

当您使用chars()显式地询问而不是时,您必须限制自己使用ASCII字符串。

pub fn reverse2(input: &str) -> String {
    // Reversing on byte-level only works with ASCII strings.
    assert!(input.is_ascii());

    let reversed_bytes: Vec<u8> = input.as_bytes().iter().copied().rev().collect();
    let reversed_string = unsafe {
        // SAFETY: This is guaranteed to be a valid UTF8 string, because:
        // - the input string is a valid ASCII string
        // - a reversed ASCII string is still a valid ASCII string
        // - an ASCII string is a valid UTF8 string
        String::from_utf8_unchecked(reversed_bytes)
    };

    return reversed_string;
}

如果您不喜欢unsafe,也可以使用checked版本,但它会带来一些开销:

pub fn reverse2(input: &str) -> String {
    // Reversing on byte-level only works with ASCII strings.
    assert!(input.is_ascii());

    let reversed_bytes: Vec<u8> = input.as_bytes().iter().copied().rev().collect();
    let reversed_string = String::from_utf8(reversed_bytes).unwrap();

    return reversed_string;
}

优化:
检查is_ascii()是一个开销,但并不是严格要求的。
UTF-8有一个特殊属性:每个非ASCII字节的值都大于或等于128。因此,从技术上讲,只要过滤掉所有大于或等于128的值就足够了:
一个二个一个一个
附加备注:
考虑使用.bytes()而不是.as_bytes().iter()

qeeaahzv

qeeaahzv2#

首先,你***应该***使用.bytes()而不是.as_bytes().iter();其次,你需要反转字符,而不是字节,因为&str可能包含UTF-8,所以使用.chars()而不是.bytes();第三,你不需要将其收集到变量中并返回变量,只需返回收集的结果;第四,你不需要显式的return
让我们总结一下我说的所有东西:

pub fn reverse2(input: &str) -> String {
    input.chars()
         .rev()
         .collect()
}
rkkpypqq

rkkpypqq3#

下面是一个将input字符串转换为字节向量的解决方案─因此可以使用Vecreverse函数:

pub fn reverse2(input: &str) -> String {
    let v = &mut input.to_string().into_bytes();
    v.reverse();
    std::str::from_utf8(v).unwrap().to_string()
}

input字符串只能包含ASCII字符。
Playground

相关问题