在Rust中反转字符串

时间:2014-07-22 01:53:43

标签: rust

我正在尝试在Rust中进行简单的字符串反转,但我似乎无法弄清楚要使用哪些函数来执行此操作。

说我有一个字符串:____x_xx__x

反转此字符串将变为:xxxx_x__xx_

我试过了:

//res is the string I want to invert
for mut c in res.as_slice().chars() {
  c =
    match c {
      'x' => '_',
       _  => 'x'
    };
};

但是这警告我永远不会读取值c,所以我猜我使用的c实际上并不是对切片中字符的引用?

3 个答案:

答案 0 :(得分:3)

.chars()会产生char个实例,这些实例不会以任何方式引用。

为了能够修改这样的东西,你需要有一个可变的切片。

String是UTF-8编码的;如果你想这样做,任何字符替换必须用于具有相同字节数的字符;最简单的情况是ASCII。 (以及x_的示例,必须为ASCII。)

实施此方法的方法是as_mut_bytes()及其mut_iter()

let bytes = unsafe { res.as_mut_slice() };
for c in bytes.mut_iter() {
    *c = match *c {
        'x' => '_',
        _ if c.len_utf8_bytes() > 1 => fail!("you tried to make me make bad UTF-8"),
        _ => 'x',
    }
}

(我插入len_utf8_bytes()分支以保证UTF-8不变。它可能会被省略 - 虽然将它作为debug_assert!仍然可能是一个好主意 - 如果你知道< / em>你只处理ASCII。)


或者,您可以从中创建一个新字符串。这将处理非ASCII字符串。

res.chars().map(|c| if c == 'x' { '_' } else { 'x' }).collect::<String>()

使用代码点作为边界也不是很精确,所以让我们在这种情况下使用grapheme clusters

res.graphemes(true).map(|c| if c == "x" { '_' } else { 'x' }).collect::<String>()

答案 1 :(得分:3)

fn main() {
    let mut res = String::from_str("____x_xx__x").into_ascii();

    for c in res.mut_iter() {
        *c = match c.to_char() {
            'x' => '_',
             _  => 'x'
        }.to_ascii();
    };

    println!("{}", res.into_string());
}

play.rust-lang.org

答案 2 :(得分:1)

这是我的看法:

http://is.gd/uXdoRf

fn new_str(s: &String) -> String {
    let mut s2 = String::new();
    for i in range(0,s.len()) {
        s2 = s2.append(if s.as_slice().char_at(i) == '_' { "x" } else { "_" });
    }
    s2
}

fn in_place(s: &mut String) {
    for _i in range(0,s.len()) {
        let c = s.shift_char();
        match c {
            Some(x) => s.grow(1,if x == '_' { 'x' } else { '_' }),
            None => return
        }
    }
}

fn main() {
    let s = String::from_str("___xxx__x_");
    let s2 = new_str(&s);
    println!("{}",s);
    println!("{}",s2);
    let mut s3 = String::from_str("___xxx__x_");
    in_place(&mut s3);
    println!("{}",s3);
}

输出:

___xxx__x_
xxx___xx_x
xxx___xx_x

令人讨厌的是,因为&#34; shift_char&#34;就地版本是O(n ^ 2)。是O(n)。我不确定如何直接改变单个角色。