【问题标题】:Erasing an element from 2D vector c++从 2D 矢量 C++ 中删除元素
【发布时间】:2014-06-25 21:08:39
【问题描述】:

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

vector< vector<int> > Test

测试 =

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

我正在阅读第 1 行,如果其中的任何元素存在于其他行中,则将其删除。 例如.. 读取第 1 行后,我必须从其他行中删除 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);
                        }
                }
        }

【问题讨论】:

  • 请细化is not working。我们不会神奇地发现您的代码发生了什么。
  • 基于这个二维向量,我的最终输出应该看起来像 {2,4,6,5,7}{9,10},没有第三和第四行,因为它们的元素之前重复.
  • 预期的输出是什么,你得到的输出是什么。如果你的擦除元素不是 i 和 j 将被关闭?
  • 你能添加你的完整代码吗?一行代码不足以确定您可能遇到的错误。
  • test[i].erase(test[i].begin()+j)test.at(i).erase(test.at(i).begin()+j) 在我本地测试时都可以工作。您能否发布整个代码,以便我们检查错误是否在其他地方?

标签: c++ vector


【解决方案1】:

也许它也不是很好,但它确实有效

#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 } {} {}
  • 如果我理解的问题是正确的,不仅第一行应该被编辑。
  • 第一行应该保持不变。只有其他行中出现的元素才会被删除。
  • 谢谢大家。我会检查的。
【解决方案2】:

您认为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 to n 开始。如果我参考您的代码,您添加的代码将放在您的

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

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

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

【讨论】:

  • 这应该是Test[i]... 修复它。所以这段代码应该在你的 for 循环中,在那里你迭代 i。
  • 输出顺序仍然不完美,但部分可以正常工作。输出应为 {2,4,6,5,7}{9,10} 最后两行元素重复。所以删除了它们。
  • 在这种情况下,最好也检查元素是否存在于上面的行中......看看新版本。它与除实际行之外的每一行进行比较。
【解决方案3】:

您可以将每行中遇到的值放在一个集合中,然后查询新行中的每个元素是否存在于该集合中。这样的函数看起来像这样:

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());
    }
}

【讨论】:

    【解决方案4】:

    这对我有用:

    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;
             }
          }
       }
    }
    

    【讨论】:

    • 我正在尝试这个,但不知何故“分段错误”
    【解决方案5】:

    考虑以下二维向量

    我的向量=

    1 2 3 4 5 -6

    6 7 8 -9

    8 -1 -2 1 0

    假设我们要删除元素 myVector[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);
     } 
    

    我们基本上做的是,我们得到要删除的元素的行和列。现在,由于这个 2D 向量是向量的向量,我们将向量(包含要删除的元素的行)和列作为参数传递给函数。请注意,行向量作为引用传递(向量参数中的“&”)。 现在问题变得非常简单,就像从一维向量中删除一个元素一样。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      相关资源
      最近更新 更多