删除C++中2D向量的元素

7

我有一个二维不对称的向量。

vector< vector<int> > Test

其中Test =

         2 4 6 5 7 
         6 5 7 9 10
         5 9 10
         9 10

我正在阅读第一行,如果在其他行中存在该行的任何元素,则将其删除。

例如.. 在读取第一行后,我必须从其他行中删除6、5和7。

然而,它没有起作用

这是我尝试的代码

Test[i].erase(Test[i].begin()+j);

其中i代表行,j代表列。

我的代码是:

for (i =0; i < Test.size();i++)
        {
        for (j=0; j < Test[i].size();j++)
                {
                // removed repeated element
                if (i >0)
                        {
                        Test[i].erase(Test[i].begin() +j);
                        }
                }
        }

3
请优化“不起作用”的代码。我们无法神奇地发现您的代码出了什么问题。 - Chnossos
基于这个二维向量,我的最终输出应该看起来像{2,4,6,5,7}{9,10},因为第三行和第四行的元素在之前已经重复出现过了。 - snoze
1
预期的输出是什么?你得到的输出是什么?如果你删除元素,那么i和j不会失调吗? - jcjunction
@snoze:我理解你想要的结果。包括我在内的两个人问过你程序的结果是什么。显然,它与你想要的不同,但你没有提到其他任何信息。如果你能看到程序输出的确切错误,那么了解程序中的错误会有所帮助。 - David K
David,我已经在上面发布了我的代码和结果。根据我的代码,我无法获得我想要的结果。 - snoze
显示剩余5条评论
5个回答

3
也许它不太漂亮,但它有效。
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main() 
{
    std::vector<std::vector<int>> v =
    {
        { 2, 4, 6, 5, 7 }, 
        { 6, 5, 7, 9, 10 },
        { 5, 9, 10 },
        { 9, 10 }
    };

    for ( const auto &row : v )
    {
        for ( int x : row ) std::cout << x << ' ';
        std::cout << std::endl;
    }

    std::cout << std::endl;

    if ( !v.empty() )
    {
        for ( auto it = std::next( v.begin() ); it != v.end(); ++it )
        {
            auto is_present = [&]( int x )
            {
                return std::find_if( v.begin(), it,
                    [x]( const std::vector<int> &v1 )
                    {
                        return std::find( v1.begin(), v1.end(), x ) != v1.end();
                    } ) != it; 
            };

            it->erase( std::remove_if( it->begin(), it->end(), is_present ), 
                       it->end() );
        }
    }


    for ( const auto &row : v )
    {
        for ( int x : row ) std::cout << x << ' ';
        std::cout << std::endl;
    }

    return 0;
}

输出是:
2 4 6 5 7 
6 5 7 9 10 
5 9 10 
9 10 

2 4 6 5 7 
9 10 

答案应为 {2 4 6 5 7 } {9 10 } {} {} - snoze
如果我理解问题正确,不仅第一行应该被编辑。 - Alex VII
首行应保持不变,如果其它行出现在此行之前,请予以删除。 - snoze
谢谢大家。我会检查它。 - snoze

2
您可以将每行遇到的值放入一个集合中,然后查询新行中的每个元素是否存在于该集合中。这样的功能应该像这样:

void RemoveRowDuplicates(vector<vector<int>> &v)
{
    std::set<int> vals;

    for(auto &vec : v)
    {
        vec.erase(remove_if(vec.begin(), vec.end(), [&](int k){
            return vals.find(k) != vals.end();
        }), vec.end());
        vals.insert(vec.begin(), vec.end());
    }
}

1

你认为 Test[i].begin()+j 到底是什么?它是你想要删除的元素集合吗?我认为不是。它应该只是一个指向单个元素的迭代器,但你想要删除已经在你的数据结构中的所有元素

如果我理解了你想做的事情,请尝试:

for(int j = 0; j < Test.size(); j++){            //iterate over other rows
    if(j == i)
        continue;
    for(int k = 0; k < Test[j].size(); k++){     //iterate over elements of the rows
        int elementToRemove = (Test[j])[k];
        vector<int>::iterator it = Test[i].begin();
        while (it != Test[i].end()) {            //iterate over row i
           if((*it) == elementToRemove){         //erase the element if it matches the actual
               it = Test[i].erase(it);    
           }else{
               it++;
           }
        }
    }
}

你可以对每个可能的i执行代码。也许从i = 0到n开始。如果我参考你的代码,你添加的代码应该放在你的中间。

for (i =0; i < Test.size();i++){
    //my code here...
}

编辑:现在使用迭代器进行删除。第一个版本是不正确的。

编辑2:更改了第一个循环的索引并添加了continue语句。


这应该是 Test[i]...已经修复了。所以这段代码应该在你的 for 循环中,你需要迭代 i。 - Alex VII
输出顺序仍不完美,但部分功能已经实现。输出应为{2,4,6,5,7}{9,10},最后两个元素重复了。因此将它们删除。 - snoze
在这种情况下,最好也检查一下元素是否存在于上面的行中...看看新版本。它与除当前行以外的每一行进行比较。 - Alex VII

0
考虑以下二维向量
myVector=
1 2 3 4 5 -6
6 7 8 -9
8 -1 -2 1 0
假设我们想要删除myVector[row][column]元素,其中row和column是适当的索引。
看一下以下代码:
void delete_element(vector<int>& temp, col) 
  {
     temp.erase(temp.begin()+col);
  }

int main()
 {
  //Assume that the vector 'myVector' is already present.
    cin>>row>>column;
    delete_element(myVector[row],column);
 } 

我们基本上所做的是,获取要删除元素的行和列。由于这个二维向量是一个向量的向量,我们将包含要删除元素的行的向量和列作为参数传递给一个函数。请注意,行向量作为引用(在向量参数中使用'&')传递。 现在问题变得非常简单,就像从一维向量中删除元素一样。
希望这可以帮助到您!

0
这对我有效:
int i = 0;
for ( int j = i+1; j < Test.size(); ++j )
{
   for ( int k = 0; k < Test[i].size(); ++k )
   {
      std::vector<int>::iterator iter = Test[j].begin();
      std::vector<int>::iterator end = Test[j].end();
      for ( ; iter != end; )
      {
         if ( *iter == Test[i][k] )
         {
            iter = Test[j].erase(iter);
         }
         else
         {
            ++iter;
         }
      }
   }
}

我正在尝试这个,但是出现了“分段错误”。 - snoze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接