Aizu Online Judge(AOJ)が提供している「プログラミング応用」(ITP2)の1_D問題をC++で解いてみました。
ITP2では、「プログラミングのための基礎ライブラリを獲得します」とあります。トピック#1では、動的配列とリストを学びます。
問題(1_D: Vector II)
問題はリンク先をご覧ください。
多重配列(Vector コンテナ)について学びます。
多重配列について
問題を読むと、n 個の可変長配列に対して操作を行うことが分かります。
このような場合は、「配列の配列」または「vector コンテナを要素に持つ vector コンテナ」として実装します。
宣言
「vector コンテナを要素に持つ vector コンテナ」の宣言について、面倒な問題がありました。vector<int> を要素に持つ、vector コンテナは、以下のように宣言できるように思えます。
vector<vector<int>> A;
C++03 では、”>>” がシフト演算子と同一の文字並びになります。そのため C++03 では、空白を入れて、以下のように書く必要がありました。
vector<vector<int> > A;
これは、さすがに不自然です。C++11 から、この空白が無くても動作するように言語規約が改訂されました。この変更については、cpprefjp 様の記事が詳しく解説しています。
初期値付きの宣言
Vector コンテナが含む要素数を宣言したい場合は、以下のように宣言します。
vector<vector<int>> A(3, vector<int>(4));
これは、3行4列の配列 A[3][4] と同じような機能を持つ Vector コンテナを提供します。
C++ プログラム例(ITP2 1_D)
問題で与えられるクエリに従い、以下の操作を行います。
- クエリ0 push_back により、A[t] に与えられた x を末尾に挿入する。
- クエリ1 与えられた t に対して、A[t] の要素をすべて出力する。
- クエリ2 A[t] を clear する。ただし空の場合は、何もしない。
1_A で紹介したプログラムをベースとします。Vector コンテナが提供するメソッドから size と empty、clear を追加して使います。最終的には以下のようなプログラムになります。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, q;
cin >> n >> q;
vector<vector<int>> A(n);
for (int i = 0; i < q; ++i) {
int command;
cin >> command;
if (command == 0) {
int t, x;
cin >> t >> x;
A[t].push_back(x);
} else if (command == 1) {
int t;
cin >> t;
if (!A[t].empty()) {
for (int j = 0; j < A[t].size(); ++j) {
if (j != 0 ) {
cout << " ";
}
cout << A[t][j];
}
}
cout << endl;
} else if (command == 2) {
int t;
cin >> t;
if (!A[t].empty()) {
A[t].clear();
}
}
}
return 0;
}
上記プログラムは、AOJ で「AC(Accepted=正解)」と判定されました。
最後に
多重のVectorコンテナは、実際のプログラムでも良く使われます。細かなことですが、C++11規格から、>> に空白が必要なくなり、書きやすくなりました。
引き続き、ITP2 の問題を紹介していきます。