有没有什么好方法可以删除向量或双端队列中的元素?提供一些示例代码非常欢迎

时间:2011-03-28 14:41:24

标签: c++ stl

例如,我好2矢量,说矢量电流,矢量to_delete。是否有一些好方法可以删除当前出现的元素。

这是我的方法。我想这看起来不太好。所以请帮帮我。谢谢。

#include <iostream>
#include <vector>
using namespace std;
int main(){
  vector <double> current;
  current.push_back(1.1);
  current.push_back(2.1); 
  current.push_back(3.1); 
  current.push_back(4.1); 
  current.push_back(5.1); 
  current.push_back(6.1); 
  current.push_back(7.1); 
  current.push_back(8.1);
  vector <double> to_delete;
  to_delete.push_back(2.1);
  to_delete.push_back(5.1);
  for(int i = 0;i<to_delete.size();i++){
    int loc = -1;
    for(int j = 0; j < current.size();j++)
    {
      if(current[j]==to_delete[i]){
        loc = j;
        break;
      }
    }
    if(loc >= 0){
      current.erase(current.begin()+loc);
    }
  }

  for(int i = 0;i < current.size();i++){
    cout << current[i]<< endl;
  }
}

4 个答案:

答案 0 :(得分:5)

可能最简单的方法是使用std::set_difference构造一个新的向量(两个向量都必须进行排序才能使其工作):

std::vector<double> diff;
std::set_difference(current.begin(), current.end(),
                    to_delete.begin(), to_delete.end(),
                    std::back_inserter(diff));

答案 1 :(得分:2)

像以下一样出了什么问题:

std::vector<double>::iterator iter
    = std::find_first_of( current.begin(), current.end(),
                          to_delete.begin(), to_delete.end() );
while ( iter != current.end() ) {
    iter = std::find_first_of( current.erase( iter ), current.end(),
                               to_delete.begin(), to_delete.end() );
}

或者,您可以定义谓词:

template <typename Container>
class IsElementOf
{
    Container const* m_container;
public:
    IsElementOf(Container const& container)
        : m_container(&container)
    {
    }

    bool operator()( typename Container::value_type const& v ) const
    {
        return std::find( m_container->begin(),
                          m_container->end(),
                          v )
                != m_container->end();
    }
};

template <typename Container>
inline IsElementOf<Container>
isElementOf( Container const& container )
{
    return IsElementOf<Container>(container);
}

并使用std :: remove_if:

current.erase(
    std::remove_if( current.begin(), current.end(),
                    isElementOf( to_delete ) ),
    current.end() );

(如果您必须这样做,这实际上只是一个有效的提案 在许多不同的地方的事情。或者如果你可以使用boost :: bind来 生成IsElementOf,但这很难,因为 编程时,编译器不会知道从哪里开始 类型,所以你必须在某处明确指定它。)

答案 2 :(得分:0)

您可以使用std::find()代替手动循环来查找应删除的元素的位置。

std::vector<double>::iterator del =
      std::find(current.begin(), current.end(), to_delete[i]);
if (del != current.end())
    current.erase(del);

答案 3 :(得分:0)

首先,您应该注意,在您的特定示例中,x.1不能完全表示为基本的两个浮点格式,并且尝试比较这些值可能会导致不平等,因为编译器生成的代码即使它似乎它应该有用。

接下来,如果您需要任意删除,vector是否真的是正确的容器?您是否考虑过使用setmultiset

如果您需要随机访问容器,则可以使用@ Space_C0wb0y建议的set_difference方法或使用std::remove

for(int i = 0;i<to_delete.size();i++)
{
    current.erase(std::remove(current.begin(), current.end(), to_delete[i]), current.end());
}

假设n = current.size()m = to_delete.size(),如果它已经排序,set_difference应该是线性的。如果未排序,则为O(n log n) + O(m log m)。删除方法为O(m n)