【问题标题】:delete and insert in random position in std::list在 std::list 中的随机位置删除和插入
【发布时间】:2021-02-03 00:56:23
【问题描述】:

我正在尝试从 stl::list 中删除随机位置。因为 List 没有随机访问迭代器,所以我想知道如何做到这一点。

#include <iostream>
#include<vector>
#include <random>
#include <list>
#include <iterator>
int main()
{
  std::random_device dev;
  std::mt19937 rng(dev());
  std::uniform_int_distribution<std::mt19937::result_type> dist6(1,99); // distribution in range [1, 99]
  std::list<int> myList;
  for(int i = 0; i<100; ++i)
  {
      myList.push_back(i);
  }
  auto it = myList.begin();
  for(int i =0; i<100/2; ++i) //remove 50 item.
  {
      //move iterator to begin + randrom number.
      //call erase with the iterator (it = myList.erase(it))
  }
  auto iter = myList.begin();
  for(int i = 0; i<100/2; ++i)
  {
     //move iterator to random position
     //insert the value of i to that location. myList.insert(iter,i)
 }

【问题讨论】:

  • 如果要随机访问,为什么要使用列表?
  • 您从列表的开头开始,并在向前迭代时开始计数。如果您已经有一个迭代器并且知道与迭代器匹配的“索引”,您可以增加或减少迭代器以移动迭代器的差异。或者您可以从开头或结尾开始,这取决于哪个更接近新位置。 std::advance 可能有用。
  • C++ 的创建者对这个用例进行了实验:isocpp.org/blog/2014/06/stroustrup-lists

标签: c++ list


【解决方案1】:

您可以使用std::advancestd::next 将迭代器推进任意数量的位置。对于链表上的迭代器,这将花费与前进位置数量呈线性关系的时间(因此,对于这样的任务,您不应该使用链表,但这就是生活)。

  using Dist = std::uniform_int_distribution<std::mt19937::result_type>;

  for(int i =0; i<100/2; ++i)
  {
      Dist dist(1, myList.size());
      auto iter = std::next(myList.begin(), dist(rng));
      myList.erase(iter);
  }
  for(int i = 0; i<100/2; ++i)
  {
     Dist dist(1, myList.size());
     auto iter = std::next(myList.begin(), dist(rng));
     myList.insert(iter, i);
 }

当/如果您决定使用支持随机访问迭代器的容器,std::nextstd::advance 将自动使用它们的能力在恒定时间内向迭代器添加偏移量,而不是线性时间重复增量用于前向迭代器或双向迭代器,因此如果您将myList 更改为std::vectorstd::deque,此代码将继续工作(并且很可能会变得更快)。

【讨论】:

  • 您应该添加位置检查;他们会盲目射击。
  • @Yakk-AdamNevraumont:……或者更好的是,只生成有效的值。
  • @JerryCoffin 擦除后向量不会使迭代器无效吗?如何在不弄乱迭代器的情况下使用向量来完成?
  • 它使那个特定的迭代器失效,但至少在这里写的代码,一旦我们删除元素,我们无论如何都会丢弃那个迭代器,并在循环的下一次迭代中创建一个新的迭代器.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多