反转字符串的一部分

pad*_*dyg 0 reverse concatenation substr rust

我正在通过codefights练习工作,并最终得到一些混乱的代码,在Python中,相对简单的字符串切片和连接:

s = "the quick (brown (fox) jumps) over"
(f, t) = (18, 21)
ss = s[:f] + s[t-1:f-1:-1] + s[t:]
Run Code Online (Sandbox Code Playgroud)

在Rust:

let s = String::from("the quick (brown (fox) jumps) over");
let sc: Vec<_> = s.chars().collect();
let (f, t) = (18, 21); // result of searching through sc
let mut new_s: Vec<_> = sc[..f].into_iter().collect();
new_s.extend(&sc[f..t].into_iter().rev().collect::<Vec<_>>());
new_s.extend(&sc[t..].into_iter().collect::<Vec<_>>());
let mut ss = String::with_capacity(new_s.len());
for c in new_s.iter() {ss.push(**c);}
Run Code Online (Sandbox Code Playgroud)

主要是通过添加东西来修复编译错误我最终得到了复杂性,我似乎无法减少.在Rust中执行此操作的"正确"方法是什么?

我没有像使用答案那样做,replace()因为这是一个简单的问题,可以搜索字符串并反转匹配括号内的部分.

Jmb*_*Jmb 5

这应该只为你的5分配两次,我不确定是否有办法摆脱中间分配:

let ss: String = s.chars()
                  .take(f)
                  .chain(s.chars().skip(f).take(t-f).collect::<Vec<_>>().into_iter().rev())
                  .chain(s.chars().skip(t))
                  .collect();
Run Code Online (Sandbox Code Playgroud)

请注意,UTF-8字符串操作比Python代码似乎暗示要复杂得多.例如,在存在组合字符(playground)的情况下,两种解决方案都无法达到预期效果.

以下摆脱了中间分配:

let ss: String = s.chars()
                  .take(f)
                  .chain(s.chars().rev().skip(s.chars().count()-t).take(t-f))
                  .chain(s.chars().skip(t))
                  .collect();
Run Code Online (Sandbox Code Playgroud)

我们需要使用s.chars().count()而不是s.len()Unicode,因为它s.len()是代码单元,我们需要代码点的长度.

这更容易理解,但仅适用于ASCII或if f和t是代码单元中的索引:

let ss: String = s[..f].chars()
                       .chain(s[f..t].chars().rev())
                       .chain(s[t..].chars())
                       .collect();
Run Code Online (Sandbox Code Playgroud)