2016-07-15 1 views
2

私はこのコードを2Dベクトルで読み込みます。 temp_vecの必要性を排除する方法はありますか?2Dベクトルを読み込むときに一時的なベクトルを削除するにはどうすればよいですか?

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]; 
    } 
} 

答えて

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アダプタはをオーバーライドして最大3を入力し、次にcollectは各Vecを構築するときにそのヒントを使用します。

マトリックスにネストされたVecを使用すると、反パターンが発生します。

もちろん、元のコードと同じです。

あなた「ブレーク」標準入力 - あなたは確実に私はあなたがここで何を意味するかわからないんだけどlock().lines()

を呼び出した後、それを使用することはできません。 stdin.read(&mut[0,0,0]).expect("Unable to read more")を追加して、let vecを定義するコードの後に​​使用できます。

stdinを使用できないという問題が発生した場合は、先に終了するブロックにロックを適用して修正できます。

+0

ありがとうございました!私の錆に関するすべての質問にお答えしているようですが、おそらくShemaaster交換所にサイトを変更する必要があります:) – KDN

+1

@KDN nah;私はここであまりにも多くの時間を過ごすだけです。できるだけ良い答えを出せる人がたくさんいますが、他の人はやっていません。また、役に立つ答えを提供することさえできない領域がたくさんあります。 – Shepmaster

3

私は、あなたがenumerate()だけがループのために渡すことができますイテレータ、で終わる、collect()呼び出しを削除:

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()を呼び出す代わりに割り当てます新しい文字列なので、追加の割り当てが1つだけになります(小さな行列をたくさん読んでいる方が恩恵を受けるかもしれません)。

(あなたのコードについての追記:あなたができるならば、それは、ベクトルのインデックスに繰り返すよりも.iter().enumerate()を使用することをお勧めします)、この答えを書くとき、私はstack-があったことを考えて、元の質問を読み違えてきた


割り当てられた行列:

const VEC_SIZE: usize = 3; 
let mut vec = [[0; VEC_SIZE]; VEC_SIZE]; 

それが事実だった場合、私は私の解決策をお勧めしますが、それはVec<Vec<i32>>だから、それはより多くの慣用的だとして、私は、Shepmasterの1 @お勧めします。

関連する問題