c++ Vectors:基于特定列中的值删除行

C++ Vectors : Deleting rows based on a value in a particular column

本文关键字:删除行 于特定 Vectors c++      更新时间:2023-10-16

我有一个2d数组(4x4),我需要根据最后一列中的特定值删除行,如果它包含字符串"NULL",则应删除整行。

在这篇文章之后,我可以删除任何包含值"NULL"的行。下面是我的代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
    vector< vector<string> > myVector;
        //m * n is the size of the matrix
    int m = 4, n = 4;
    //Grow rows by m
    myVector.resize(m);
    for(int i = 0 ; i < m ; ++i)
    {
        //Grow Columns by n
        myVector[i].resize(n);
    }
    //Now you have matrix m*n with default values
    //you can use the Matrix, now
    myVector[0][0] = "DC:86:D8:0F:EA:B8";
    myVector[0][1] = "NULL";
    myVector[0][2] = "1";
    myVector[0][3] = "NULL";
    myVector[1][0] = "18:F6:43:E7:ED:2E";
    myVector[1][1] = "1";
    myVector[1][2] = "1";
    myVector[1][3] = "-34";
    myVector[2][0] = "AC:81:12:57:12:50";
    myVector[2][1] = "1";
    myVector[2][2] = "1";
    myVector[2][3] = "NULL";
    myVector[3][0] = "00:C1:41:28:0B:6F";
    myVector[3][1] = "1";
    myVector[3][2] = "NULL";
    myVector[3][3] = "-23.5";

    for (int i =0; i<m; i++)
    {
        for (int j =0; j<n; j++)
        {

             cout<< myVector[i][j] <<"t";
        }
        cout<<endl;
    }
    vector<vector<string> >::iterator row;
    vector<string>::iterator col;
for (row = myVector.begin(); row != myVector.end(); ) {
    bool delRow = false;
    for (col = row->begin(); col != row->end(); col++) {
        if (*col == "NULL") {
           delRow = true;
           break;
        }
    }    
    if (delRow) {
       row = myVector.erase(row);
    } else {
       ++row;
    }
}
    cout<<endl;
    cout<<endl;
    cout<<endl;
    cout<<endl;
    cout<<endl;
    cout<<endl;
    for (row = myVector.begin(); row != myVector.end(); row++)
    {
        for (col = row->begin(); col != row->end(); col++)
        {
            // do stuff ...cout << row;
            cout << *col <<"t";
        }
        cout<<endl;
    }
    cout<<endl;
    cout<<endl;
    cout<<endl;
    cout << "The size is " << myVector.size();
       return 0;
}

我怎么能改变上面的代码,使它只迭代最后一列,并删除行,如果列包含"NULL"?我尝试使用for (col = row->end();;),但它不起作用。我也尝试使用帖子中建议的擦除习语,但它会给我编译错误。

myVector.erase(
    std::remove_if(myVector.begin(), myVector.end(), [](const auto& row) {
        for(const auto& col : row){
           if(col == "NULL") { return true; }
        }
        return false;
    }), myVector.end());

这里从前到后遍历一行。

for (col = row->begin(); col != row->end(); col++) {
        if (*col == "NULL") {
           delRow = true;
           break;
        }
    }

相反,你应该只检查最后一列,像这样:

vector<string>::reverse_iterator last = row->rbegin();
if( *last == "NULL"){
     delRow=true;
}

在行上使用反向迭代器,即从后面开始的迭代器,如果增加它,它将移动到前面。但是,由于您只想检查最后一个元素,因此不需要在列上执行for -循环。这是一个很好的解决方案,如果你知道它总是你携带的最后一个条目,即使在某些时候你在每行中有更多的条目或不同长度的行。

另一种可能更通用的方法是沿着if( (*row)[3]=="NULL")评论中提到的行。但是我不会建议将3硬编码到代码中。而是使用另一个变量(例如int colOfInterest = 3),然后使用它if( (*row)[colOfInterest]=="NULL")。像这样,如果突然你感兴趣的列不是第三列而是第一列,你可以在一个地方改变它。当别人读你的代码时,真的很难理解为什么你在固定的地方有一个3,用注释来解释这些事情也不太好——变量使它更显式(可能比我建议的名字更好,也不会有坏处),如果在某些时候你碰巧关心同一列中的其他值,变量可以在代码的其他部分重用。

正如你所看到的,有不同的方法来处理你的问题,这都取决于"你要去哪里"。这也是为什么我写了一个评论,我建议你去https://codereview.stackexchange.com/。在你的代码中还有很多值得讨论的东西