C++のgenerate()とgenerate_n()を使ったテストケースの自動生成方法
本記事では、C++のSTL(標準テンプレートライブラリ)関数を使ってテストケースを効率的に生成する方法を解説します。配列を扱うプログラムのテストケースを手動で作成するのは、非常に手間がかかり非効率な作業になりがちです。そこで活躍するのが、C++が標準で提供している2つの便利な関数です。
generate()メソッドとは
C++のstd::algorithm::generate()は、引数なしで呼び出されるジェネレータ関数(gen)が返す値を、指定した範囲[first, last)内のすべての要素に順番に代入する関数です。この関数は3つのパラメータを受け取ります。
- first:範囲の先頭位置を指す前方イテレータ
- last:範囲の末尾位置を指すイテレータ
- gen:引数なしで呼び出され、値を返すジェネレータ関数
サンプルコード
以下の実装例を見て、具体的な動作を確認してみましょう。
#include <bits/stdc++.h>
using namespace std;
int create_random() {
return (rand() % 1000);
}
int main () {
srand(time(NULL));
vector<int> data(15);
generate(data.begin(), data.end(), create_random);
for (int i=0; i<data.size(); i++)
cout << data[i] << " " ;
}実行結果
449 180 785 629 547 912 581 520 534 778 670 302 345 965 107
この例では、15個の要素を持つvectorに対して、0から999までのランダムな整数がすべての要素に代入されます。srand(time(NULL))によって乱数のシードを初期化しているため、実行するたびに異なる結果が得られます。
generate_n()メソッドとは
C++のstd::algorithm::generate_n()は、ジェネレータ関数(gen)が返す値を、先頭位置から数えて最初のn個の要素にのみ代入する関数です。こちらも3つのパラメータを受け取ります。
- first:範囲の先頭位置を指す前方イテレータ
- n:値を代入する要素の個数(呼び出し回数)
- gen:引数なしで呼び出され、値を返すジェネレータ関数
サンプルコード
以下の実装例で動作を確認してみましょう。
#include <bits/stdc++.h>
using namespace std;
int create_random() {
return (rand() % 1000);
}
int main () {
srand(time(NULL));
vector<int> data(15);
generate_n(data.begin(), 6, create_random);
for (int i=0; i<data.size(); i++)
cout << data[i] << " " ;
}実行結果
540 744 814 771 254 913 0 0 0 0 0 0 0 0 0
この例では、vectorの先頭から6個の要素だけにランダムな値が代入され、残りの9個の要素は初期値の0のままになっています。コンテナ全体ではなく一部の要素だけを更新したい場合に、generate_n()は特に便利です。
まとめ
generate()とgenerate_n()を使い分けることで、テストデータの生成処理を簡潔かつ効率的に記述できます。競技プログラミングやアルゴリズムの検証などでランダムなテストケースが必要な場面で、ぜひ活用してみてください。
-
C++で円と長方形の重なりを判定するアルゴリズム
問題の概要円を (radius, xc, yc) という形式で表します。ここで (xc, yc) は円の中心座標です。同様に、軸に平行な長方形(軸平行境界ボックス)を (x1, y1, x2, y2) という形式で表し、(x1, y1) が左下隅の座標、(x2, y2) が右上隅の座標とします。このとき、円と長方形が互いに重なっているかどうかを判定する必要があります。たとえば、次のような入力が与えられた場合を考えてみましょう。この場合、出力は true(重なりあり)となります。解決のアプローチこの問題を解く鍵は、「長方形の中で円の中心に最も近い点」を見つけることです。その点と円の中心との距離が
-
C++で解くドミノとトロミノを使ったタイル敷き詰め問題(2×Nボード)
問題の概要本記事では、「ドミノ」と「トロミノ」という2種類の形状を使ったタイル敷き詰め(タイリング)問題をC++で解く方法を解説します。これらのピースは、以下のように回転させて使用することができます。タイリングでは、盤面上のすべてのマスを必ずタイルで覆わなければなりません。また、2つのタイリング方法は、盤上の4方向に隣接する2つのセルにおいて、片方のタイリングだけがその両方のマスを同じタイルで占有している場合に限り「異なる」とみなされます。入力と出力の例整数Nが与えられたとき、2×Nのボードを敷き詰める方法が何通りあるかを求めます。例えば、入力が3の場合、出力は5となります。敷き詰め方は以下の