gpt4 book ai didi

c++ - 从 std::vector> 中删除任意项目列表

转载 作者:行者123 更新时间:2023-11-30 04:06:14 24 4
gpt4 key购买 nike

我有一个 vector 的 vector ,代表一个数组。我想有效地删除行,即以最小的复杂性和分配

我考虑过构建一个新的 vector vector ,只复制未删除的行,使用 move 语义,如下所示:

    //std::vector<std::vector<T> > values is the array to remove rows from
//std::vector<bool> toBeDeleted contains "marked for deletion" flags for each row

//Count the new number of remaining rows
unsigned int newNumRows = 0;
for(unsigned int i=0;i<numRows();i++)
{
if(!toBeDeleted[i])
{
newNumRows++;
}
}


//Create a new array already sized in rows
std::vector<std::vector<T> > newValues(newNumRows);

//Move rows
for(unsigned int i=0;i<numRows();i++)
{
if(!toBeDeleted[i])
{
newValues[i] = std::move(values[i]);
}
}

//Set the new array and clear the old one efficiently
values = std::move(newValues);

这是最有效的方法吗?

编辑:我只是认为我可以通过迭代向下 move 行来避免分配新数组,这可能会稍微更有效并且代码更简单:

    unsigned int newIndex = 0;
for(unsigned int oldIndex=0;oldIndex<values.size();oldIndex++)
{
if(!toBeDeleted[oldIndex])
{
if(oldIndex!=newIndex)
{
values[newIndex] = std::move(values[oldIndex]);
}

newIndex++;
}
}
values.resize(newIndex);

谢谢!

最佳答案

这可以使用通常的 erase-remove idiom 的变体来解决。 , 在 std::remove_if 中有一个 lambda在要删除的索引的迭代器范围内查找当前行的索引:

#include <algorithm>    // find, remove_if
#include <iostream>
#include <vector>

template<class T>
using M = std::vector<std::vector<T>>; // matrix

template<class T>
std::ostream& operator<<(std::ostream& os, M<T> const& m)
{
for (auto const& row : m) {
for (auto const& elem : row)
os << elem << " ";
os << "\n";
}
return os;
}

template<class T, class IdxIt>
void erase_rows(M<T>& m, IdxIt first, IdxIt last)
{
m.erase(
std::remove_if(
begin(m), end(m), [&](auto& row) {
auto const row_idx = &row - &m[0];
return std::find(first, last, row_idx) != last;
}),
end(m)
);
}

int main()
{
auto m = M<int> { { 0, 1, 2, 3 }, { 3, 4, 5, 6 }, { 6, 7, 8, 9 }, { 1, 0, 1, 0 } };
std::cout << m << "\n";

auto drop = { 1, 3 };
erase_rows(m, begin(drop), end(drop));

std::cout << m << "\n";
}

Live Example .

注意:因为从 C++11 开始,std::vector具有 move 语义,在你的 std::vector<std::vector<T>> 中随机排列行使用简单的指针操作完成,无论您的类型如何 T (不过,如果您想要删除,情况就会大不相同!)。

关于c++ - 从 std::vector<std::vector<T>> 中删除任意项目列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22993774/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com