在 vector<int> 中定义的索引处从 vector<string> 中删除一个字符串
Removing a string from vector<string> at index defined in vector<int>
我想根据整数向量的索引删除字符串向量的项。
尽管我可以很好地编译代码,但循环崩溃了。
#include <vector>
#include <string>
using std::string;
using std::vector;
int main()
{
vector<string> s = { "foo", "bar", "random_word" };
vector<int> i = { 0, 1 };
for (int n = 0; n < i.size(); ++n)
{
s.erase(s.begin() + i[n]);
}
}
编辑:这是导致问题的实际代码:
// The vector in which the elements to be deleted are defined consists of
// { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }.
//The identifier is i.
// The other vector consists of
// { "Bancheri", "Bertagna", "Buzzoni", "Canepa", "De Vita", "Di Bella",
// "Drago", "Esposito", "Fossati", "Francini", "Frontini", "Lorenzi",
// "Marusceac", "Miscio", "Padovani", "Scarfo'", "Sieni", "Thea Cioni",
// "Zunino" } and its identifier is s.
for (int p = 0; p < i.size(); ++p)
{
s.erase(s.begin() + s[i])
}
// This is how I fixed it:
for (int r = i.size() - 1; r > 0; --r)
{
s.erase(s.begin() + i[r]);
}
如您所见,我只是做了一个反向循环。
这种方法的问题在于,一旦 i[n]
处的项目被删除,它后面的所有索引都会向后移动一个。
为了让这个程序运行,排序 i
,并从大到小迭代。
正如已经指出的那样,崩溃的原因是索引失效 - 所有大于 i[n]
的索引都必须在删除第 i[n]
个元素后减 1。
通过按降序遍历索引容器,确保任何时刻都不存在大于i[n]
的索引,因此无需调整其他索引,因此排序i
确实解决了问题。
然而,由于 std::vector
是一个连续的数组,一个一个地擦除元素通常不是一个好主意。在您的情况下,重新排列代码以一次性完成所有擦除操作相当容易:
std::sort(i.begin(),i.end());
i.push_back(s.size()); //just to make sure the whole vector is visited
auto iter = s.begin();
int current_index = 0;
for(int index : i)
{
while(current_index < index)
{
*(iter++) = s[current_index++];
}
current_index++;
}
s.erase(iter, s.end());
如果您有能力用某个值表示要删除的元素,例如一个空字符串,它会变得更好:
for(int index : i)
s[index] = "";
s.erase(std::remove(s.begin(),s.end(),""),s.end());
我想根据整数向量的索引删除字符串向量的项。
尽管我可以很好地编译代码,但循环崩溃了。
#include <vector>
#include <string>
using std::string;
using std::vector;
int main()
{
vector<string> s = { "foo", "bar", "random_word" };
vector<int> i = { 0, 1 };
for (int n = 0; n < i.size(); ++n)
{
s.erase(s.begin() + i[n]);
}
}
编辑:这是导致问题的实际代码:
// The vector in which the elements to be deleted are defined consists of
// { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }.
//The identifier is i.
// The other vector consists of
// { "Bancheri", "Bertagna", "Buzzoni", "Canepa", "De Vita", "Di Bella",
// "Drago", "Esposito", "Fossati", "Francini", "Frontini", "Lorenzi",
// "Marusceac", "Miscio", "Padovani", "Scarfo'", "Sieni", "Thea Cioni",
// "Zunino" } and its identifier is s.
for (int p = 0; p < i.size(); ++p)
{
s.erase(s.begin() + s[i])
}
// This is how I fixed it:
for (int r = i.size() - 1; r > 0; --r)
{
s.erase(s.begin() + i[r]);
}
如您所见,我只是做了一个反向循环。
这种方法的问题在于,一旦 i[n]
处的项目被删除,它后面的所有索引都会向后移动一个。
为了让这个程序运行,排序 i
,并从大到小迭代。
正如已经指出的那样,崩溃的原因是索引失效 - 所有大于 i[n]
的索引都必须在删除第 i[n]
个元素后减 1。
通过按降序遍历索引容器,确保任何时刻都不存在大于i[n]
的索引,因此无需调整其他索引,因此排序i
确实解决了问题。
然而,由于 std::vector
是一个连续的数组,一个一个地擦除元素通常不是一个好主意。在您的情况下,重新排列代码以一次性完成所有擦除操作相当容易:
std::sort(i.begin(),i.end());
i.push_back(s.size()); //just to make sure the whole vector is visited
auto iter = s.begin();
int current_index = 0;
for(int index : i)
{
while(current_index < index)
{
*(iter++) = s[current_index++];
}
current_index++;
}
s.erase(iter, s.end());
如果您有能力用某个值表示要删除的元素,例如一个空字符串,它会变得更好:
for(int index : i)
s[index] = "";
s.erase(std::remove(s.begin(),s.end(),""),s.end());