【问题标题】:What containers are valid to use with std::random_shuffle?哪些容器可以与 std::random_shuffle 一起使用?
【发布时间】:2020-07-23 19:55:56
【问题描述】:

哪些容器可以与std::random_shuffle( RandomIt first, RandomIt last ) 一起使用?

API description 说这两个迭代器需要是随机访问迭代器——我想我不清楚什么是随机访问迭代器,特别是为什么 std::vector::begin()::end() 是,但是std::setstd::unordered_set 相同。

#include <algorithm>
#include <set>
#include <unordered_set>
#include <vector>

int main( int argc, char* argv[] )
{
  std::set<int> s = { 1, 2, 3, 4, 5 };
  std::unordered_set<int> u = { 1, 2, 3, 4, 5 };
  std::vector<int> v = { 1, 2, 3, 4, 5 };

  std::random_shuffle( s.begin(), s.end() ); // compile error
  std::random_shuffle( u.begin(), u.end() ); // compile error
  std::random_shuffle( v.begin(), v.end() ); // :)

  return 0;
}

【问题讨论】:

  • 不要使用std::random_shuffle。它在 C++14 中被弃用,在 C++17 中被移除。请改用std::shuffle

标签: c++ stl containers shuffle random-access


【解决方案1】:

如果您查看set,然后查看iterator 类成员,它将告诉您迭代器类型,在本例中为BidirectionalIterator。 (为此目的可以忽略“遗留”位)。

对于random_shuffle,它必须是RandomAccessIterator,这意味着迭代器可以在任何整数大小的跳转中移动(或者换句话说,可以通过整数索引在恒定时间内访问容器元素)。

这对于vector 是可能的(从一开始就偏移一个索引),但对于set 是不可能的,其中到达第 N 个元素的唯一方法是一次遍历元素(因为它被存储为一棵树)。

关于迭代器的更多信息:Types of iterator : Output vs. Input vs. Forward vs. Random Access Iterator

我在容器与迭代器类型的标准中找不到表,但是如果您查看this container property table,那么任何支持operator[] 整数索引的容器都是随机访问,否则不是。这就是&lt;array&gt;&lt;vector&gt;&lt;deque&gt;。 (maps 以不同的方式使用 operator[])。还有&lt;string&gt; 没有出现在该表中,当然还有任何提供随机访问迭代器的用户定义容器。

注意。 set 是一个已排序的容器,因此无论如何它都不能被随机打乱。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    相关资源
    最近更新 更多