我想检查一个向量,如果它的元素同时具有整数A和B,删除它们之间的元素并复制到另一个向量。例如,有两个向量; vector<> path
和vector<> v1
Path v1
---A***B## ---AB##
所以任务是删除A和B之间的元素 这是一个C ++代码,但不幸的是它没有用。有什么问题是什么?
vector< > Path,v1;
vector<int>::iterator it2,it3;
int A,B;
it2=find(Path.begin(), Path.end(), A) ;
it3=find(Path.begin(), Path.end(), B) ;
vector<int> v1(Path.begin(),Path.end());
if (it2 != Path.end() && it3 != Path.end())
{
if(it2<it3)
{
v1.erase(it2+1,it3);
}
else
{
v1.erase(it3+1,it2);
}
}
答案 0 :(得分:4)
首先,您在if块中创建了一个新的v1
,但我很确定您要分配给已经存在的那个。{}您还将Path
向量中的迭代器传递给v1
的擦除函数,从而导致未定义的行为。我还会保存v1.erase
所做的工作,而不是首先添加不需要的元素。
if (it2 != Path.end() && it3 != Path.end())
{
if(it3<it2)
{
std::swap(it2,it3);
}
++it2; // simplifies logic later
// optional step to possibly save an allocation
size_t total = std::distance(Path.begin(), it2);
total += std::distance(it3,Path.end());
v1.reserve(total);
v1.assign(Path.begin(), it2);
v1.insert(v1.end(), it3, Path.end());
}
请注意,如果A==B
,则会将该元素添加两次。我不确定这是否是您想要的行为,但它符合您的问题描述。
答案 1 :(得分:1)
首先,不需要从头开始遍历矢量两次,而不是使用两次算法std :: find,你可以使用算法组合std :: find_first_of和std :: find
例如
int a[] = { A, B }; // where A and B some integer values
std::vector<int>::iterator first, last;
first = last = path.end();
first = std::find_first_of( path.begin(), path.end(), std::begin( a ), std::end( a ) );
if ( first != path.end() )
{
last = std::find( std::next( first ), path.end(), *first == a[0] ? a[1] : a[0] );
}
现在要移动给定范围内的元素,您可以编写
std::vector<int> v1;
if ( first != path.end() && last != path.end() )
{
++first;
v1.assign( first, last );
path.erase( first, last );
}
或者如果不改变原始矢量那么你可以写
std::vector<int> v1;
if ( first != path.end() && last != path.end() )
{
++first;
v1.assign( path.begin(), first );
v1.insert( v1.end(), last, path.end() );
}