我如何(c++ STL)二进制搜索抽象类
How do I (C++ STL) binary_search for Abstract classes?
可以使用STL二进制搜索算法(binary_search, upper_bound, lower_bound)在基指针向量中搜索派生对象,如下所示。由于Base是抽象的(受保护的构造函数),因此必须为搜索函数实例化派生对象,这有点难看。
我想搜索给定时间以上的第一个派生向量。我能做到这一点,而不随意选择和实例化我的许多继承类之一吗?
#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 = %.1fn",data,time);
}
};
class Derived : public Base {
public:
Derived(double t, int d) : Base(t,d) {}
virtual void print() {
printf("Derived: data=%d, time=%.1fn",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();
}
程序打印:时间下界=3.5:导出:data=4, time=4.4
比较的对象不必与容器的内容类型相同,它只需要是可以与容器进行比较的对象:
#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;
}
你必须制造某种Base
的假设是错误的。你可以定义一个适合你的比较的BaseKey
,只要你的显式(或隐含)比较运算符知道要做什么。
下面的注释也是错误的,正如下面这个更复杂的例子所示:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct A {
int x;
A(int _x) :x(_x) { }
bool operator < (double d) { return x < d; }
};
int main()
{
vector<A> v;
v.push_back(A(1));
v.push_back(A(2));
v.push_back(A(3));
int i = (lower_bound(v.begin(), v.end(), 1.5))->x;
cout << i << endl;
}
您还可以显式地使用比较类型(这有助于解决操作顺序问题,例如您可能在upper_bound
中发现的问题):
class CompareADouble {
public:
bool operator () (const double d, A& a) { return d < a.x; }
};
int main()
{
vector<A> v;
v.push_back(A(1));
v.push_back(A(2));
v.push_back(A(3));
int i = (upper_bound(v.begin(), v.end(), 1.5, CompareADouble()))->x;
cout << i << endl;
}
提供多态性比较的binary_search
示例:
class CompareADouble {
public:
bool operator () (const double d, A& a) { return d < a.x; }
bool operator () (A& a, const double d) { return a.x < d; }
};
...
bool exists = binary_search(v.begin(), v.end(), 1.5, CompareADouble());
cout << exists << endl; // false
exists = binary_search(v.begin(), v.end(), 1.0, CompareADouble());
cout << exists << endl; // true because 1.0 < 1 == false && 1 < 1.0 == false
您可以传递一个空指针,并设计比较函数忽略它,只测试另一个对象的特定属性
在某种程度上,可以通过使用静态方法:
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的实例从一开始就违背了Base是抽象的目的。
相关文章:
- 有根的二进制搜索树.保留与其父级的链接
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 二进制搜索树叶数问题
- 为什么二进制搜索在我的测试中不起作用
- 正在尝试重载二进制搜索树分配运算符
- 我的二进制搜索程序只是关闭了
- 二进制搜索的终止点
- 递归二进制搜索与字符串数组
- 测试树是否为二进制搜索树
- 如何二进制搜索结构向量并在适当的索引处插入
- 如果你有一个固定大小的数组,你需要遍历它!n次,使用二进制搜索如何改变时间复杂性
- 字符串的递归二进制搜索-C++
- 使用二进制搜索树中的迭代器对象访问左侧节点
- 二进制搜索树没有匹配的函数调用
- 二进制搜索不适用于特定输出
- 如何在向量上进行二进制搜索以找到具有特定id的元素
- 二进制搜索树不变的标头文件
- 二进制搜索树插入带参数参考
- 二进制搜索不变以查找元素的首次出现
- 了解一种神秘地起作用的递归二进制搜索算法