C ++的std ::矢量搜索值(c++ std::vector search for value)

2019-08-05 07:28发布

我试图优化std::vector通过基于向量的索引和迭代,并返回匹配“搜索”标准元素- “搜索”

struct myObj {
   int id;
   char* value;
};

std::vector<myObj> myObjList;

创建独特的几千项id的和值,并将其推到矢量myObjList

什么是检索最有效的方式myObj的匹配id 。 目前我迭代指数,如:

for(int i = 0; i < myObjList.size(); i++){
   if(myObjList.at(i).id == searchCriteria){
    return myObjList.at(i);
   }
}

注: searchCriteria = int 。 所有元素具有唯一id的。 以上做这项工作,但可能不是最有效的方式。

Answer 1:

C ++标准库有一些抽象的算法,这给C ++是一种功能性的味道 ,我叫它,它可以让你更专注于您的搜索比你如何实现搜索本身的标准。 这适用于很多其他的算法。

您正在寻找该算法std::find_if ,通过迭代器区间简单的线性搜索。

在C ++ 11,你可以使用lambda来表达您的标准:

std::find_if(myObjList.begin(), myObjList.end(), [&](const myObj & o) {
    return o.id == searchCriteria;
});

当不具有C ++ 11可用,则必须提供一个谓词(功能对象(=算符)或函数指针)如果所提供的实例是你正在寻找的其中一个返回true。 函子的优势在于他们可以参数化 ,你的情况,你要参数与您正在寻找的ID仿函数。

template<class TargetClass>
class HasId {
    int _id;
public:
    HasId(int id) : _id(id) {}
    bool operator()(const TargetClass & o) const {
        return o.id == _id;
    }
}

std::find_if(myObjList.begin(), myObjList.end(), HasId<myObj>(searchCriteria));

此方法返回指向找到的第一个元素符合你标准的迭代器。 如果不存在这样的元件中,结束迭代器被返回(其指向过去矢量的末端,而不是最后一个元素)。 所以,你的函数看起来是这样的:

vector<myObj>::iterator it = std::find_if(...);

if(it == myObjList.end())
    // handle error in any way
else
    return *it;


Answer 2:

使用std::find_if

有被引用的页面上的例子。

下面是一个更精确地适合你的问题的工作示例:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct myObj
{
   int id;
   char* value;

   myObj(int id_) : id(id_), value(0) {}
};

struct obj_finder
{
    obj_finder(int key) : key_(key)
    {}

    bool operator()(const myObj& o) const
    {
        return key_ == o.id;
    }

    const int key_;
};

int main () {
  vector<myObj> myvector;
  vector<myObj>::iterator it;

  myvector.push_back(myObj(30));
  myvector.push_back(myObj(50));
  myvector.push_back(myObj(100));
  myvector.push_back(myObj(32));

  it = find_if (myvector.begin(), myvector.end(), obj_finder(100));
  cout << "I found " << it->id << endl;

  return 0;
}

而且,如果你有C ++ 11可用,您可以使用Lambda使这个更简洁:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct myObj
{
   int id;
   char* value;

   myObj(int id_) : id(id_), value(0) {}
};

int main ()
{
  vector<myObj> myvector;
  vector<myObj>::iterator it;

  myvector.push_back(myObj(30));
  myvector.push_back(myObj(50));
  myvector.push_back(myObj(100));
  myvector.push_back(myObj(32));

  int key = 100;

  it = find_if (myvector.begin(), myvector.end(), [key] (const myObj& o) -> bool {return o.id == key;});
  cout << "I found " << it->id << endl;

  return 0;
}


Answer 3:

这是不是一个真正的回答你的问题。 谁回答其他人给了不错的答案,所以我没有什么要补充给他们。

我想说,虽然你的代码是不是很地道的C ++。 真正地道的C ++会,当然,使用::std::find_if 。 但是,即使你没有::std::find_if你的代码仍然不地道。 我会提供两个重新写入。 一种的C ++ 11重新写入,并且所述第二一个C ++ 03重新写入。

首先,C ++ 11:

for (auto &i: myObjList){
   if(i.id == searchCriteria){
      return i;
   }
}

其次,C ++ 03:

for (::std::vector<myObj>::iterator i = myObjList.begin(); i != myObjList.end(); ++i){
   if(i->id == searchCriteria){
      return *i;
   }
}

通过任何类型的C ++容器的去的标准方法是使用一个迭代。 这是很好的载体可以通过整数索引。 但是,如果你依赖于行为不必要,你让它更难于自己,如果你要在以后更改数据结构。



Answer 4:

如果ID进行排序,你可以执行二进制搜索(还有一个功能binary_search在STL)。 如果他们不是什么都不会表现得更好,但你仍然可以编写代码中使用STL(使用更短的方式find_if )。



文章来源: c++ std::vector search for value