问题是:
周杰伦借了一个朋友的咖啡杯,不知何故失去了它。由于他的朋友在发现这件事时会非常生气,杰伊决定给他的朋友买一个替换杯来试图控制伤害。 不幸的是,杰伊不记得他借来的那个杯子的颜色。他只知道颜色是白色,黑色,蓝色,红色或黄色。 杰伊绕着他的办公室问他的同事他们是否能够回忆起颜色,但他的朋友似乎也不记得那个杯子的颜色。他们所知道的是杯子绝对不是什么颜色。 根据这些信息,帮助杰伊弄清楚这个杯子的颜色是什么。我正在采取的方式:
我创建了一个所有可能颜色的矢量:白色,黑色,蓝色,红色或黄色。然后要求用户输入他将要提问的同事人数。然后获取颜色建议,并为每个条目将其与向量进行比较。如果它在那里,我会把颜色弹出来。最终只有一种颜色留在矢量中,这是丢失的杯子的颜色。
我的问题:
输入第一种颜色后出现错误,我无法找出原因。确切的错误是:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
Abort (core dumped)
我的代码是:
#include <iostream>
#include <string>
#include <algorithm>
#include <climits>
#include <stdio.h>
#include <vector>
using namespace std;
int main(int argv, char* argc[])
{
string color;
vector<string> colorVector;
colorVector.push_back("White");
colorVector.push_back("Black");
colorVector.push_back("Blue");
colorVector.push_back("Red");
colorVector.push_back("Yellow");
int numColleagues;
cout<< "Please enter the number of Colleagues" << endl;
cin >> numColleagues;
cout<< "Please enter each suggested color" << endl;
int counter = 0;
while (counter < numColleagues) {
getline(cin, color);
counter++;
for (int i = 0; i < 5; i++) {
if (colorVector.at(i) == color) {
colorVector.erase(colorVector.begin() + i);
}
}
}
return 0;
}
答案 0 :(得分:1)
您正在删除向量的元素,但是您希望访问所有五个元素(循环从0到5)。所以,让我们先删除第一个,然后尝试访问第4个元素。超出范围!
所以改变你的循环:
colorVector.erase(std::remove(colorVector.begin(),
colorVector.end(), color), colorVector.end());
更多关于erase-remove idiom。
答案 1 :(得分:0)
当你调用vector::erase
时,它将返回一个指向删除元素后面元素的新位置的迭代器。所以,如果我们删除这个元素:
1 2 3 4 5 6
^
我们的迭代器将自动更新为指向5.因此我们不必再次增加迭代器,它已经增加了一些。考虑到这一点:
auto it = colorVector.begin();
for (; it != colorVector.end(); /* do not increment it */ )
{
if (*it == color)
{
it = colorVector.erase(it); // erase and update
}
else
{
++it; // just update
}
}
当然,使用不易出错的算法会更好
colorVector.erase(
std::remove(colorVector.begin(), colorVector.end(), color),
colorVector.end()
);
答案 2 :(得分:-1)
您正在迭代期间修改 colorVector 。
一旦删除其中一种颜色,向量突然只有4个项目。现在,当你尝试转到第5项(在删除之前可以安全做) - 它崩溃了
试试这个:
for (int i = 0; i < colorVector.size(); i++) {
if (colorVector.at(i) == color) {
colorVector.erase(colorVector.begin() + i);
--i;
}
}
通过停在 colorVector.size 而不是硬编码 5 ,您可以确保列表永远不会超出范围。
编辑:
添加了--i语句以避免跳过下一个
Edit2:
正如下面的评论所述,从您当前正在迭代的阵列中删除项目通常是一个坏主意。