C++ 矢量擦除错误

C++ 矢量擦除错误,c++,vector,C++,Vector,我有以下C++代码: #include <iostream> #include <cstdlib> #include <ctime> #include <vector> int main () { srand(time(0)); int noOfElements = 9; for (int a = 0; a < 9; a++) { std::vector<int> poss;

我有以下C++代码:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
int main ()
{
    srand(time(0));
    int noOfElements = 9;
    for (int a = 0; a < 9; a++)
    {
        std::vector<int> poss;
        for (int a = 1; a <= 9; a++)
            poss.push_back(a);
        for (int b = 0; b < 9; b++)
        {
            int random = rand() % 9;
            std::cout << poss[random];
            poss.erase(random);
            noOfElements--;
        }
        std::cout << "\n";
    }
}
#包括
#包括
#包括
#包括
int main()
{
srand(时间(0));
int noOfElements=9;
对于(int a=0;a<9;a++)
{
std::向量poss;
对于(int a=1;a不能直接从向量中擦除值(向量是序列容器,而不是关联容器):需要为要擦除的元素提供迭代器

为了获得迭代器,您可以:

  • 根据元素的值(例如通过使用)查找元素,然后在成员函数的输入中提供返回的迭代器,或
  • 通过向迭代器应用一个偏移量来获得它,迭代器指向向量的开头(即成员函数返回的对象)
在第一种情况下

#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v { 1, 2, 3};
    auto i = std::find(begin(v), end(v), 2);
    v.erase(i);
}
或者(仅限C++11),您可以执行以下操作:

next(begin(v), pos);

你必须传递一个迭代器才能擦除。所以试试吧

poss.erase(poss.begin() + random);

向量擦除函数不接受迭代器值。 此外,还需要检查边界条件,以查看正在擦除的索引是否超出范围

std::vector<int>::iterator itr = poss.begin() + random;
if(itr != poss.end())
{
  poss.erase(itr);
}
std::vector::iterator itr=poss.begin()+random;
如果(itr!=poss.end())
{
可能擦除(itr);
}

你是想擦除一个随机位置还是一个随机值?这会产生很大的不同。如果你使用标准算法,这会更短、更健壮。
std::iota
替换你的第一个内部循环,并且
std::random\u shuffle
将它们洗牌。
std::copy
可以输出它们,并且
std::vector::clear
可以重置向量。一旦
擦除
开始工作,您需要将
rand()%9
更改为
rand())%noOfElements
。我没有遇到
std::iota
。整洁。我还没有找到一个完整、完整且易于阅读的列表,列出C++11中的所有新功能……我认为这是一个正确的答案,但安迪·普劳尔可能是对的。@john是的,我同意,我打算编辑我的帖子,说我不确定OP的意图。我也有关于OP的循环将超过数组末尾的问题——我想进一步分析一下逻辑,让自己相信它是正确的(或者可能只是添加一些要检查的内容,例如在
assert(random
的行中,在这种情况下,我想他最有可能想要
std::vector::iterator it=poss.begin()+random;std::cout@Chowlett:重新阅读这个问题,似乎你是对的。起初我认为,
random
是OP想要删除的值,而不是它的位置。但可能不是这样,所以我更新了我的答案以涵盖这两种情况。谢谢你,你所做的边界检查非常不充分。它检查迭代器aga请列出一个可能的无效值。当然,形成任何超出范围的迭代器都是未定义的行为。因此,如果确实要进行范围检查,则应在将其添加到
poss.begin()之前对整数进行检查
。当然,如果您完全控制整数的生成,就像这里的情况一样,那就是整数值应该绑定的地方:
int random=rand()%poss.size();
。任何额外的检查都是多余的。
next(begin(v), pos);
poss.erase(poss.begin() + random);
std::vector<int>::iterator itr = poss.begin() + random;
if(itr != poss.end())
{
  poss.erase(itr);
}