假设我在变量c中有char,在变量n中有正int.我想要建立包含c发生n次的str.我该怎么做呢?

我试着将它构建为String,可能只是试图阅读有关字符串的文档时感到头晕,但我不知道如何将其转换为str.但如果我试图直接把它造成str,那么我也看不到如何做到这一点.

对于上下文,以下是我试图实现的完整功能.它获取一个字符串并查找最长的连续字符序列(并通过获取出现的第一个字符来打破平局).

pub fn longest_sequence(s: &str) -> Option<&str> {
    if s.len() == 0 { return None; }
    let mut current_c = s.as_bytes()[0] as char;
    let mut greatest_c = s.as_bytes()[0] as char;
    let mut current_num = 0;
    let mut greatest_num = 0;
    for ch in s.chars() {
        if current_c == ch {
            current_num += 1;
            if current_num > greatest_num {
                greatest_num = current_num;
                greatest_c = current_c;
            }
        } else {
            current_num = 1;
            current_c = ch;
        }
    }
    // Now build the output str ...
}

推荐答案

我认为对strString有几个误解.

  • str永远不能单独存在.它始终用作&str(或Box<str>*str,但在您的情况下,这些都不重要).
  • &str不拥有任何数据.它只是对另一个String的(部分)引用.
  • String实际上保存着数据.
  • 所以当你想返回data时,使用String;如果你想返回reference existing data,则返回&str.
  • is no way将本地的String转换为&str.数据必须存储在某个地方,而&str不会存储它.(为了完整起见:是的,您可以泄露它,但这将在内存中创建一个永远不会消失的字符串)

因此,在您的情况下,有两种方式:

  • 引用输入&str,因为它的数据已经存储在某个地方.
  • 相反,返回String分.

作为附注:不要做s.as_bytes()[0] as char,因为它will not work与UTF8-字符串. rust 串被定义为UTF8.

这里有一个可能的解决方案:

pub fn longest_sequence(s: &str) -> Option<&str> {
    let mut current_c = s.chars().next()?;
    let mut current_start = 0;
    let mut current_len = 0;
    let mut greatest: &str = "";
    let mut greatest_len = 0;
    for (pos, ch) in s.char_indices() {
        if current_c == ch {
            current_len += 1;
        } else {
            if greatest_len < current_len {
                greatest = &s[current_start..pos];
                greatest_len = current_len;
            }

            current_len = 1;
            current_c = ch;
            current_start = pos;
        }
    }

    if greatest_len < current_len {
        greatest = &s[current_start..];
    }

    Some(greatest)
}

pub fn main() {
    let s = "????????????????????€€????????";

    let seq = longest_sequence(s);
    println!("{:?}", seq);
}
Some("????????????")

以下是一些解释:

  • 不需要判断空字符串.s.chars().next()?会自动执行此操作.
  • 使用s.chars().next()而不是s.as_bytes()[0] as char,因为第二个不兼容UTF8.
  • 我明确地存储greatest_len而不是使用greatest.len(),因为greatest.len()也不兼容UTF8,因为它给出的字符串大小是bytes,而不是chars.
  • 每当找到相同值的新字符时,就存储新的最大字符串;我必须将其移到字符类型发生变化的情况下(并且在循环之后),因为我们don't仍然知道当前字符的结尾.同样,请注意,&s[current_start..current_start+current_len]不起作用,因为&s[ .. ]希望索引在bytes中,而current_lenchars中.因此,我们需要等待另一个字符才能知道前一个字符在哪里结束.

基于您的代码的另一种解决方案是:

pub fn longest_sequence(s: &str) -> Option<String> {
    let mut current_c = s.chars().next()?;
    let mut greatest_c = current_c;
    let mut current_num = 0;
    let mut greatest_num = 0;
    for ch in s.chars() {
        if current_c == ch {
            current_num += 1;
            if current_num > greatest_num {
                greatest_num = current_num;
                greatest_c = current_c;
            }
        } else {
            current_num = 1;
            current_c = ch;
        }
    }

    // Build the output String
    Some(std::iter::repeat(greatest_c).take(greatest_num).collect())
}

pub fn main() {
    let s = "????????????????????€€????????";

    let seq = longest_sequence(s);
    println!("{:?}", seq);
}
Some("????????????")

Rust相关问答推荐

为什么单元类型(空元组)实现了`Extend`trait?

使用Rust s serde_json对混合数据类型进行优化'

亚性状上位性状上的 rust 病伴生型界限

为什么实例方法可以像Rust中的静态方法一样被调用?

在跨平台应用程序中使用std::OS::Linux和std::OS::Windows

如何高效地将 struct 向量中的字段收集到单独的数组中

如何使用reqwest进行异步请求?

为什么AsyncRead在Box上的实现有一个Unpin特征绑定?

从管道读取后重置标准输入

如何在 Rust 中编写一个通用方法,它可以接受任何可以转换为另一个值的值?

Rust Option 的空显式泛型参数

Rust LinkedList 中的borrow 判断器错误的原因是什么?

Rust FFI 和 CUDA C 性能差异

Rust中的一生语法有什么作用?

在发布中包含 Rust DLL

如何从trait方法返回std :: iter :: Map?

如何获得对数组子集的工作可变引用?

如何重写这个通用参数?

为什么 u64::trailing_zeros() 在无分支工作时生成分支程序集?

为什么 Bevy 的 Trait 边界不满足 Rapier 物理插件?