我试图优化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
的。 以上做这项工作,但可能不是最有效的方式。
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;
使用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;
}
这是不是一个真正的回答你的问题。 谁回答其他人给了不错的答案,所以我没有什么要补充给他们。
我想说,虽然你的代码是不是很地道的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 ++容器的去的标准方法是使用一个迭代。 这是很好的载体可以通过整数索引。 但是,如果你依赖于行为不必要,你让它更难于自己,如果你要在以后更改数据结构。
如果ID进行排序,你可以执行二进制搜索(还有一个功能binary_search
在STL)。 如果他们不是什么都不会表现得更好,但你仍然可以编写代码中使用STL(使用更短的方式find_if
)。