rust - 反转字符串的一部分

标签 rust concatenation reverse substr

我正在努力完成 codefights 练习,结果得到了一些困惑的代码,在 Python 中,这是相对简单的字符串切片和连接:

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

在 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);}

主要是通过添加一些东西来修复编译错误,我最终遇到了似乎无法降低的复杂性。在 Rust 中执行此操作的“正确”方法是什么?

我没有使用 replace() 做类似答案的事情,因为这是一个简化的问题示例,用于搜索字符串并反转匹配括号内的部分。

最佳答案

这应该只为你的 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();

请注意,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();

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

这更容易理解,但仅适用于 ASCII 或如果 ft 是代码单元中的索引:

let ss: String = s[..f].chars()
                       .chain(s[f..t].chars().rev())
                       .chain(s[t..].chars())
                       .collect();

关于rust - 反转字符串的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47456000/

相关文章:

rust - 迭代获取子节点的可变引用

unit-testing - 如何为 Rust 测试中的所有测试函数创建一个具有作用域/生命周期的变量?

带有空字符串的 c 标记粘贴(连接)

python - 以相反的顺序从numpy数组中获取一些元素

python - 给定一个句子,返回一个单词颠倒的句子

c - 倒数算法错误

rust - 是否可以在不使用匹配的情况下将 Option<Result<T, E>> 转换为 Result<Option<T>, E>?

macros - 如何在宏中命名任意序列的事物?

ruby-on-rails - Rails 3 中的字符串连接

java - 在 Java 中连接两个整数以获得 float