C++ 如何(C+;+;STL)二进制搜索抽象类?
可以使用STL二进制搜索算法(二进制搜索、上界、下界)搜索派生对象的基指针向量,如下所示。由于Base是抽象的(受保护的构造函数),因此必须为搜索函数实例化一个派生对象,这有点难看 我想搜索给定时间上导出的第一个向量。我可以在不随意挑选和实例化我的许多继承类中的一个的情况下做到这一点吗C++ 如何(C+;+;STL)二进制搜索抽象类?,c++,stl,abstract,binary-search,C++,Stl,Abstract,Binary Search,可以使用STL二进制搜索算法(二进制搜索、上界、下界)搜索派生对象的基指针向量,如下所示。由于Base是抽象的(受保护的构造函数),因此必须为搜索函数实例化一个派生对象,这有点难看 我想搜索给定时间上导出的第一个向量。我可以在不随意挑选和实例化我的许多继承类中的一个的情况下做到这一点吗 #include <algorithm> #include <vector> #include <stdio.h> using namespace std; class Ba
#include <algorithm>
#include <vector>
#include <stdio.h>
using namespace std;
class Base {
protected:
Base(double t, int d) : data(d), time(t) {}
public:
double time;
int data;
virtual void print() {
printf("Base: data = %d, time = %.1f\n",data,time);
}
};
class Derived : public Base {
public:
Derived(double t, int d) : Base(t,d) {}
virtual void print() {
printf("Derived: data=%d, time=%.1f\n",data,time);
}
};
struct BaseTimeComp {
bool operator()(Base* a, Base* b) { return a->time < b->time; }
};
int main()
{
vector<Base*> v;
for(int i=0; i<5; i++) { v.push_back(new Derived(i+0.4,i)); }
Base* pLow = *(lower_bound(v.begin(),v.end(),
new Derived(3.5,0), //NOT "new Base(3.5,0)"
BaseTimeComp()));
printf("lower bound for time=3.5:\n");
pLow->print();
}
#包括
#包括
#包括
使用名称空间std;
阶级基础{
受保护的:
基(双t,int d):数据(d),时间(t){}
公众:
双倍时间;
int数据;
虚拟空打印(){
printf(“基:数据=%d,时间=%.1f\n”,数据,时间);
}
};
派生类:公共基{
公众:
派生(双t,int d):基(t,d){
虚拟空打印(){
printf(“派生:数据=%d,时间=%.1f\n”,数据,时间);
}
};
结构BaseTimeComp{
bool操作符()(Base*a,Base*b){返回a->timetime;}
};
int main()
{
向量v;
对于(int i=0;iprint();
}
该程序打印:
时间下限=3.5:
派生:data=4,time=4.4您可以传递空指针,并设计比较函数忽略它,仅测试另一个对象的特定属性。您可以传递空指针,并设计比较函数忽略它,仅测试另一个对象的特定属性。在某种程度上,您可以使用static方法:
class Base {
...
public:
static Base *newSearchInstance(double t, int d) {return new Base(t,d);};
...
};
在对LowerBound的调用中:
Base* pLow = *(lower_bound(v.begin(),v.end(),
Base::newSearchInstance(3.5,0), //<------
BaseTimeComp()));
Base*pLow=*(下限(v.begin(),v.end(),
Base::newSearchInstance(3.5,0),//您可以通过使用静态方法:
class Base {
...
public:
static Base *newSearchInstance(double t, int d) {return new Base(t,d);};
...
};
在对LowerBound的调用中:
Base* pLow = *(lower_bound(v.begin(),v.end(),
Base::newSearchInstance(3.5,0), //<------
BaseTimeComp()));
Base*pLow=*(下限(v.begin(),v.end(),
Base::newSearchInstance(3.5,0),//比较的目标不必是与容器内容相同的类型,只需是可以与容器进行比较的内容:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
int i = *(lower_bound(v.begin(), v.end(), 1.5)); // <<< NOTE: floating point "value"
cout << i << endl;
}
您还可以显式地使用比较类型(这有助于解决操作顺序问题,例如您可能会在上限
中发现的问题):
比较的目标不必是与容器内容相同的类型,它只需是您可以与容器进行比较的内容:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
int i = *(lower_bound(v.begin(), v.end(), 1.5)); // <<< NOTE: floating point "value"
cout << i << endl;
}
您还可以显式地使用比较类型(这有助于解决操作顺序问题,例如您可能会在上限
中发现的问题):
+1:Grim!但我认为它会起作用。函子每次都必须检查它的哪个参数是NULL
,并相应地翻转逻辑。+1:Grim!但我认为它会起作用。函子每次都必须检查它的哪个参数是NULL
,并相应地翻转逻辑。是的,确实如此违背目的。是的,这确实违背了目的。-1:这不起作用。在这个特定的例子中,1.5
将被简单地转换为int
,作为下限
的参数。在一个更复杂的例子中,它根本不会编译。我请你编译更复杂的例子,或者解释更多它必须是复杂的…@Ben:现在用上界
或二进制搜索
,或者用一个自定义的比较器函数/函子试试…@Ben:有趣。我不认为这会编译(尽管我相信它只通过利用下界
的特定实现来编译,等等).好的,那么在我取消否决票之前的最后一个问题:使用自定义比较器进行二进制搜索?@Ben:即使在例如下限
的情况下,我认为定义比较器的两种排列方式是最安全的。从技术上讲,STL实现可以选择在任何方向进行比较。-1:这不起作用。在这篇文章中例如,1.5
将简单地转换为int
,作为下限
的参数。在更复杂的示例中,它根本无法编译。我邀请您编译更复杂的示例,或者解释它必须有多复杂…@Ben:现在用上限
或二进制搜索尝试一下
,或者使用自定义比较器函数/functor…@Ben:很有趣。我不认为这会编译(尽管我相信它只通过利用下限
等的特定实现进行编译).好的,在我取消否决票之前的最后一个问题是:binary\u search
,使用自定义比较器?@Ben:即使在例如lower\u bound
的情况下,我认为定义比较器的两种排列是最安全的。从技术上讲,STL实现可以选择在任何方向进行比较。