【问题标题】:How do I convert a string to a list of chars?如何将字符串转换为字符列表?
【发布时间】:2018-05-29 12:06:42
【问题描述】:

由于字符串支持迭代但不支持索引,我想将字符串转换为字符列表。我有"abc",我想要['a', 'b', 'c']

它可以是任何类型,只要我可以索引到它。 Vec<char>[char; 3] 可以,其他想法也很有趣!

更快会更好,因为我正在处理很长的字符串。假设字符串是 ASCII 时效率更高的版本也很酷。

【问题讨论】:

  • 我想知道你为什么需要索引它?也许这是一个 XY 问题。您在 std 库中有太多工具可以处理字符串,我看不出有任何理由寻找对字符串的随机访问。
  • 我在工作,公司屏蔽了聊天。我问这个问题,因为也许你的问题可以在不索引字符的情况下解决。

标签: rust


【解决方案1】:

我已经找到了这个解决方案:

let chars: Vec<char> = input.chars().collect();

在评论中有人建议使用.split(""),但它的实现方式似乎对这种情况很烦人:

println!("{:?}", "abc".split("").collect::<Vec<&str>>());

["", "a", "b", "c", ""]

【讨论】:

  • 如果你想要一个Vec&lt;&amp;str&gt;split("") 会给你,但你不希望开头和结尾的空字符串,使用split_terminator("").skip(1)
【解决方案2】:

Stringstr 上使用chars 方法:

fn main() {
    let s = "Hello world!";
    let char_vec: Vec<char> = s.chars().collect();
    for c in char_vec {
        println!("{}", c);
    }
}

你有一个live example

【讨论】:

  • 您也可以在 str 上调用 chars() 并省略 to_string()。
【解决方案3】:

由于您尝试解决 Advent of Code 的第一天,我假设您需要比较两个连续的字符并根据字符是否相同来更新累加器。您可以通过在chars 上使用fold 函数来执行此操作而无需索引。像这样的东西(未经测试):

fn example(s: &str) -> u32 {
    let mut i = s.chars()
        .map(|c| c.to_digit(10).expect("Invalid input: Non-digit found!"));
    if let Some(first) = i.next() {
        let (tot, last) = i.fold((0, first), |acc, x| {
            let (tot, prev) = acc;
            if prev == x {
                (tot + prev, x)
            } else {
                (tot, x)
            }
        });
        if last == first {
            tot + last
        } else {
            tot
        }
    } else {
        0
    }
}

fold 迭代器方法允许您遍历所有迭代器项,在每一步更新该值。这里的值是一个包含累积结果和前一个数字的值的元组。我们用一些初始结果和第一个字符的值来初始化它。然后在每一步中,我们将当前字符与从当前值中取出的前一个字符进行比较,根据比较结果更新累加结果,并使用更新后的累加器和当前字符返回一个新值。

fold 方法返回最后一个值,在我们的例子中包含累加结果和最后一个字符,此时您可以检查最后一个字符是否与第一个相同,并根据需要更新结果到。

【讨论】:

  • 有趣的想法。对于问题的第一部分,我有类似的想法,但认为以这种方式区别对待开头和结尾有点混乱。在第二部分中,偏移量有所不同,这变得不可行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 2020-06-07
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
相关资源
最近更新 更多