【问题标题】:Removing fields in c++ vector删除 C++ 向量中的字段
【发布时间】:2013-01-20 03:37:44
【问题描述】:

我无法正确掌握这个想法和编程这样的事情(我是初学者): 我有一个向量。向量可以说元素:fieldA、fieldB、fieldC。因此,有了这些向量的数组,我想检查,从数组中的最后一个向量开始,然后转到第一个向量的方向,如果其中一个元素具有特定值,可以说 if (vect[i].字段A == 0.0)。在这种情况下,如果 (vect[i-1].fieldA == 0.0) so 具有相同的值,我想从数组中删除整个向量。有人可以为我提供一部分可视化的代码,如何创建正确的“反向迭代”循环并使用函数删除它?我正在尝试使用erase()、remove()、deque(),但我失败了。

我不想在这里弄乱我的代码。

感谢您的帮助!

编辑。所以我首先在我的数组中循环输入向量值,然后我想从最后删除所有包含元素特定值的向量,例如字段A == 0.0

我想切割数组,而不仅仅是删除向量的内容! classB 和 classA 之间存在适当的继承,因此馈送效果很好,我只想通过删除向量来解决这个问题。 示例:包含 2 个元素的向量数组。输入:0,1 0,3 3,3 2,3 0,6 5,6 0,8 0,7 0,6 输出:0,1 0,3 3,3 2,3 0,6 5,6 0 ,8。结论:0,7和0,6向量被删除。

    classA tmp;
    for (std::vector<std::classB>::iterator iter = newW.begin(); iter != newW.end(); iter++)
        {
        tmp.set_fieldA(iter->a);
        tmp.set_fieldB(iter->b);
        tmp.set_fieldC(iter->c);
        objA.push_back(tmp);
        }

    vector<std::classA> objA;
        for(int i = objA.size()-1; i > 0; i--)
        {
        if (objA[i].fieldA == 0.0)
            if (objA[i-1].fieldA == 0.0)
                objA.erase(objA[i-1]); //remove last vector from array
        }

【问题讨论】:

  • 很难从问题中准确理解发生了什么。如果您到目前为止向我们展示您的代码,那么有人可能会告诉您如何修复它。
  • 另外,如果你从数组中删除一个向量,这意味着你有一个二维数组,比如向量的向量?
  • @makciook 我认为这个上下文中的向量实际上是一个class 和成员fieldA 等,这些被存储在一个数组中(或者可能是std::vector)?这就是我要代码的原因;不是很清楚。
  • 对不起,我现在提供了我写的代码
  • 乍一看,我发现的一个错误是您在应该填充它的循环之后声明了您的std::vector&lt;std::classA&gt; objA。您应该将声明移到第一个循环上方。

标签: c++ algorithm vector iteration erase-remove-idiom


【解决方案1】:

我将您的代码解释如下。你有一个名为 Vector 的 struct 有 3 个成员

struct Vector
{
    double fieldA;
    double fieldB;
    double fieldC;
}

下面的代码工作如下。它使用std::find_if_not反向迭代器rbegin()rend())从后面查找第一个fieldA0 不同的元素。然后它将其转换为常规迭代器(使用base())并将其与向量的末尾进行比较。最后调用v.erase实际上会擦除它们(所谓的erase-remove idiom

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>

int main()
{

   struct Vector { int fieldA; int fieldB; };
   std::vector<Vector> v = { 
      Vector{ 1, 0 }, Vector{ 2, 1 }, Vector{ 0, 2 }, Vector{ 1, 3 }, Vector{ 0, 4 }, 
      Vector{ 0, 5 }, Vector{ 5, 6 }, Vector{ 6, 7 }, Vector{ 0, 8 }, Vector{ 0, 9 }, Vector{ 0, 10} 
   };   

   for (auto& e: v) { std::cout << "{" << e.fieldA << "," << e.fieldB << "}, "; };
   std::cout << "\n";

   auto m = std::find_if_not(v.rbegin(), v.rend(), [&](Vector const& elem){
       return elem.fieldA == 0;
   }).base();

   if (m != v.end())
      // remove all but one matching element
      v.erase(m + 1, v.end());

   for (auto& e: v) { std::cout << "{" << e.fieldA << "," << e.fieldB << "}, "; };
   std::cout << "\n";   
}

LiveWorkSpace 上的输出

【讨论】:

  • 这不是我的意思。如果数组中的任何元素包含 0,我不想移动它们。我想将它们从数组的末尾删除,这样最后是一个不包含 0 的向量(因为可能根本没有 0) ,或者只有一个向量包含 0,而不是更多。例子:0,1 2,1 2,2 0,4 0,5 1,6 0,8 0,7 0,6 -> 我想在这里去掉0,7和0,6,得到0, 1 2,1 2,2 0,4 0,5 1,6 0,8
  • @berndh 已更新,包含新的代码示例。它将 0,8 项留在后面,但会删除任何其他带有 0 的尾随元素。
  • 谢谢,在线我看到它有效,但是当我在 Visual 中尝试时,我得到错误 C2552: 'v' : non-aggregates cannot be initialized with initializer list, v.push_back 也不起作用对我来说,因为“不接受多个论点”。你有什么建议吗?
  • @berndh Visual C++ 2012 年 11 月 CTP 确实有初始化列表,除了所有库代码(包括 std::vector)。这将在下一个版本中提供。同时,只需使用一组 push_back() 调用逐个加载项目,或者创建一个 std::array(Visual C++ 可以使用初始化列表)并创建一个循环将该数组复制到向量中。跨度>
  • 不幸的是,这也不起作用,find_if_not 无法识别。有没有其他方法? (以便 Visual 采用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 2013-07-02
相关资源
最近更新 更多