2026-09-18
join_lines.rs
fn join_lines(lines: &[&str]) -> String {
// write this: join lines with '\n' between them, allocating the
// result's buffer exactly once via String::with_capacity
// (no + or format! inside the loop)
}
join_linesを実装してください。ループの中で+やformat!を使わず、必要なバイト数を先に数えてString::with_capacityで確保してからpush_strで詰めること。
Reference
fn join_lines(lines: &[&str]) -> String {
let total_len: usize = lines.iter().map(|line| line.len() + 1).sum();
let mut result = String::with_capacity(total_len);
for (i, line) in lines.iter().enumerate() {
if i > 0 {
result.push('\n');
}
result.push_str(line);
}
result
}
push_str自体もバッファが足りなくなれば自動で確保し直しますが、そのたびに前の内容をコピーし直すコストが発生します(ならし計算量ではO(n)ですが、確保は複数回起こり得ます)。先に全行の長さの合計を数えてString::with_capacityで一度だけ確保しておけば、その後のpush_strは再確保なしで済み、確保は最初の1回だけになります。これは参考実装であり、唯一の正解ではありません。