我有这个代码用于在2D矢量中读取。有没有办法消除temp_vec
的需要?
let mut vec_size: usize = 3;
let mut vec = vec![vec![0; vec_size]; vec_size];
for i in 0..vec_size{
input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read");
let temp_vec: Vec<i32> = input
.split_whitespace()
.map(|s| s.parse().unwrap())
.collect();
for j in 0..temp_vec.len(){
vec[i][j] = temp_vec[j];
}
}
答案 0 :(得分:3)
我删除collect()
调用,最终得到一个迭代器,你可以enumerate()
并传递给for循环:
use std::io;
fn main() {
let vec_size: usize = 3;
let mut vec = vec![vec![0; vec_size]; vec_size];
let mut input = String::new();
for i in 0..vec_size {
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read");
let numbers = input
.split_whitespace()
.map(|s| s.parse().unwrap());
for (j, x) in numbers.enumerate() {
vec[i][j] = x;
}
}
}
此代码还调用clear()
来清除输入缓冲区而不是分配新的字符串,因此它只需要一个额外的分配(如果你正在阅读很多小矩阵,你可能会从中受益)。
(关于你的代码的旁注:如果可以的话,使用.iter().enumerate()
比迭代矢量索引更好)
在写这个答案时,我误解了原来的问题,认为有一个堆栈分配的矩阵:
const VEC_SIZE: usize = 3;
let mut vec = [[0; VEC_SIZE]; VEC_SIZE];
如果是这种情况,我会推荐我的解决方案,但由于它是Vec<Vec<i32>>
,我推荐@ Shepmaster's,因为它更具惯用性
答案 1 :(得分:1)
将标准输入的行映射为行,然后将每行中的数字映射为列。
use std::io;
use std::io::prelude::*;
const SIZE: usize = 3;
fn main() {
let stdin = io::stdin();
let vec: Vec<Vec<i32>> = stdin.lock()
.lines()
.take(SIZE)
.map(|line| {
let line = line.expect("Unable to read line");
line.split_whitespace()
.take(SIZE)
.map(|s| s.parse().expect("Enable to parse number"))
.collect()
})
.collect();
println!("{:?}", vec);
}
或者如果你不在乎恐慌:
use std::io;
use std::io::prelude::*;
use std::error::Error;
const SIZE: usize = 3;
fn main() {
let stdin = io::stdin();
let vec: Result<Vec<Vec<i32>>, _> = stdin.lock()
.lines()
.take(SIZE)
.map(|line| {
line.map_err(|e| Box::new(e) as Box<Error>)
.and_then(|line| {
line.split_whitespace()
.take(SIZE)
.map(|s| s.parse().map_err(|e| Box::new(e) as Box<Error>))
.collect()
})
})
.collect();
println!("{:?}", vec);
}
解决评论中的问题:
您的代码会进行2n + 1次分配(如果有人在寻找性能,这很重要
目前还不清楚N
是什么,但最多应分配3个向量,每个向量中有3个项目。 take
适配器将覆盖size_hint
以最多3
,然后collect
将在构建每个Vec
时使用该提示。
对矩阵使用嵌套的
Vec
是一个反模式。
当然,但这就是原始代码所做的。
你“打破”stdin - 在调用
后你无法可靠地使用它lock().lines()
我不确定你的意思。我能够在定义stdin.read(&mut[0,0,0]).expect("Unable to read more")
的代码块之后添加let vec
,表明它可以被使用。
如果无法使用stdin存在问题,您可以通过将锁定范围限定为更早结束的块来修复它。