我正在尝试在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
实际上并不是对切片中字符的引用?
答案 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());
}
答案 2 :(得分:1)
这是我的看法:
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)。我不确定如何直接改变单个角色。