0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

すべての "行の長さと値が不定" な 2 次元配列の出力

Posted at

Paizaの問題を解いてたら、最初のコードで全部 1 から順に並んじゃって大混乱。よく考えたら index の管理をミスってた…。Iteratorslice() を使えばスッキリ解決するから、複数の解法を紹介するよ!

問題の概要

入力:

  • 1行目:数列の長さ N と行グループの数 M
  • 2行目:N 個の数列 A
  • 3行目:各グループのサイズ B

出力:

  • M 個のグループごとに A の一部を出力(各行の末尾にはスペースなし)

入力例

5 2
1 2 3 4 5
2 3

出力例

1 2
3 4 5


NG例(僕の最初の失敗)

for (let i = 0; i < M; i++){
    for(let k = 0; k < row[i]; k++){
        if(k+1 === row[i]){
            process.stdout.write(nums[k] + "\n");
        }else {
            process.stdout.write(nums[k] + " ");
        }
    }
}

ミス:

  • nums[k] を毎回 0 から参照してるせいで、出力が全部 1 から始まる…。


OK例(解決法)

解法1:Iterator を使う

const [N, M] = lines[0].split(" ").map(Number);
const nums = lines[1].split(" ").map(Number);
const row = lines[2].split(" ").map(Number);

const iter = nums.values();
for (let i = 0; i < M; i++){
    for(let j = 0; j < row[i]; j++){
        if(j + 1 === row[i]){
            process.stdout.write(iter.next().value + "\n");
        }else{
            process.stdout.write(iter.next().value + " ");
        }
    }
}

ポイント:

  • nums.values()Iterator を作成
  • iter.next().value を使って値を順番に取得


解法2:index で管理

let index = 0;
for (let i = 0; i < M; i++) {
    let output = [];
    for (let j = 0; j < row[i]; j++) {
        output.push(nums[index++]);
    }
    console.log(output.join(" "));
}

ポイント:

  1. output 配列を用意し、row[i] の個数分だけ値を取得
  2. join(" ") でスペース区切りの文字列に変換し、一括で console.log
  3. indexnums のインデックスを管理


解法3:slice() を使う

const [N, M] = lines[0].split(" ").map(Number);
const A = lines[1].split(" ").map(Number);
const B = lines[2].split(" ").map(Number);

let begin = 0;
for (let i = 0; i < M; i++) {
    let end = begin + B[i];
    console.log(A.slice(begin, end).join(" "));
    begin = end;
}

解説:

  1. N, M を取得(N: 数列の長さ, M: グループの数)
  2. A を数列として取得(例: [1, 2, 3, 4, 5]
  3. B をグループのサイズとして取得(例: [2, 3]
  4. begin を 0 に初期化
  5. end = begin + B[i] を計算し、適切な範囲を取得 (slice(begin, end))。
  6. begin = end に更新して、次のグループの処理へ進む。

処理の流れの例:

  • begin = 0, end = 2A[0] から A[1] を出力 → 1 2
  • begin = 2, end = 5A[2] から A[4] を出力 → 3 4 5

ポイント

  • begin はグループの開始位置、 end はグループの終了位置を表す。
  • slice(begin, end) を使うことで簡潔に部分配列を取得できる。

まとめ

Iterator を使うとスッキリ解決!
index を管理すればシンプルに書ける!
slice() を使うと直感的!


僕の失敗談と解決話!

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?