| 45 | |
| 46 | template <typename T> |
| 47 | std::vector<T> create_random_array(const size_t size, const T rand_min, const T rand_max) |
| 48 | { |
| 49 | assert(rand_min <= rand_max); |
| 50 | assert(size <= static_cast<size_t>(rand_max - rand_min + 1)); |
| 51 | |
| 52 | // メルセンヌ・ツイスタ作成 |
| 53 | auto random_engine = create_random_engine(); |
| 54 | std::uniform_int_distribution<T> uniform_int_distribution(rand_min, rand_max); |
| 55 | |
| 56 | // sizeより少し大きくランダム数列(重複あり)を作成する |
| 57 | const auto make_size = static_cast<size_t>(size * 1.2); |
| 58 | |
| 59 | // vがsizeになるまで繰り返す |
| 60 | std::vector<T> v; |
| 61 | v.reserve(size); |
| 62 | while (v.size() != size) |
| 63 | { |
| 64 | // ランダム整数列を順に追加(重複がある可能性がある) |
| 65 | while (v.size() < make_size) |
| 66 | { |
| 67 | v.push_back(uniform_int_distribution(random_engine)); |
| 68 | } |
| 69 | |
| 70 | // ソートして重複を除く -> 重複が除かれた数列の末尾のイテレータがunique_endに入る |
| 71 | std::sort(v.begin(), v.end()); |
| 72 | auto unique_end = std::unique(v.begin(), v.end()); |
| 73 | |
| 74 | // vのサイズが大きすぎたら,sizeまでのイテレータに変えておく |
| 75 | if (size < static_cast<size_t>(std::distance(v.begin(), unique_end))) |
| 76 | { |
| 77 | unique_end = std::next(v.begin(), size); |
| 78 | } |
| 79 | |
| 80 | // 重複部分から最後までを削除する |
| 81 | v.erase(unique_end, v.end()); |
| 82 | } |
| 83 | |
| 84 | // 昇順になっているのでシャッフル |
| 85 | std::shuffle(v.begin(), v.end(), random_engine); |
| 86 | |
| 87 | return v; |
| 88 | } |
| 89 | |
| 90 | // 明示的に実体化しておく |
| 91 | template std::vector<int> create_random_array(size_t, int, int); |
no test coverage detected