GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • cpprefjp - C++日本語リファレンス
  • GitHub Project

This view

  • Original page
  • New address

GeezerVison is showing cpprefjp.github.io — std::shuffle - cpprefjp C++日本語リファレンス

  1. リファレンス
  2. algorithm
  3. shuffle

最終更新日時: 2026年08月26日 16時18分05秒 (JST)
Akira Takahashi が更新

履歴 編集

function template
<algorithm>

std::shuffle(C++11)

namespace std {
  template <class RandomAccessIterator, class UniformRandomBitGenerator>
  void shuffle(RandomAccessIterator first, RandomAccessIterator last,
               UniformRandomBitGenerator&& g);
}

概要

[first,last) のそれぞれの要素を同じ確率で並び替える。

要件

  • RandomAccessIterator は ValueSwappable の要件を満たしている必要がある。
  • UniformRandomBitGenerator は uniform random bit generator の要件を満たさなければならず、その戻り値の型は iterator_traits<RandomAccessIterator>::difference_type へ変換可能でなければならない。

計算量

正確に (last - first) - 1 回 swap する。

備考

以下の実装では、フィッシャー - イェーツのシャッフルアルゴリズムが使用されている:

  • GCC: 4.9 (libstdc++)
  • Clang: 3.4 (libc++)
  • Visual C++: 2013

例

整数の配列をシャッフルする

#include <algorithm>
#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>
#include <random>
#include <cstdint>

int main() {
  std::vector<int> v(10);
  std::iota(v.begin(), v.end(), 0); // 0~9 までの値を生成

  std::cout << "before: ";
  std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout));
  std::cout << std::endl;

  // シャッフル
  std::random_device seed_gen;
  std::uint32_t seed = seed_gen();
  std::mt19937 engine(seed);
  std::shuffle(v.begin(), v.end(), engine);

  std::cout << " after: ";
  std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout));
  std::cout << std::endl;
}

出力例

before: 0123456789
 after: 5803429716

文字列をシャッフルする

#include <algorithm>
#include <iostream>
#include <string>
#include <random>
#include <cstdint>

int main() {
  std::string input = "0123456789abcdef";

  std::cout << "before: " << input << std::endl;

  // シャッフル
  std::random_device seed_gen;
  std::uint32_t seed = seed_gen();
  std::mt19937 engine(seed);
  std::shuffle(input.begin(), input.end(), engine);

  std::cout << " after: " << input << std::endl;
}

出力例

before: 0123456789abcdef
 after: 49e351b8f0ad62c7

実装例

template <class RandomAccessIterator, class UniformRandomBitGenerator>
void shuffle(RandomAccessIterator first, RandomAccessIterator last, UniformRandomBitGenerator&& g) {
  if (first == last) return;

  using distance_type   = typename iterator_traits<RandomAccessIterator>::difference_type;
  using unsigned_type   = typename make_unsigned<distance_type>::type;
  using distribute_type =          uniform_int_distribution<unsigned_type>;
  using param_type      = typename distribute_type::param_type;

  distribute_type d;
  for (auto it = first + 1; it != last; ++it)
    iter_swap(it, first + d(g, param_type(0, it - first)));
}

関連項目

  • ranges::shuffle

参照

  • LWG Issue 1432. random_shuffle signatures are inconsistent
    • C++11で、乱数生成器の引数型が左辺値参照から右辺値参照へ改められた。一時オブジェクトの乱数生成器を渡せるようにするため
  • P0346R1 A <random> Nomenclature Tweak
    • URNGをURBGに変更
  • LWG Issue 2716. Specification of shuffle and sample disallows lvalue URNGs
    • C++17で、乱数生成器の要件がremove_reference_tを通して判定されるよう整理され、左辺値の乱数生成器を渡せることが明確化された
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.