鉴于:
typedef .../*some type*/ SomeValue;
SomeValue someFunction(int arg){
return /*some calculation involving arg that produces SomeValue*/
}
int firstCandidate = 0, lastCandidate = 101;
SomeValue desiredValue = SomeValue();
我想找到int
参数,它使用二分搜索(desiredValue
)生成someFunction
(传递给std::lower_bound
时)。
firstCandidate
,lastCandidate
是要赋予someFunction
的参数。
对于搜索候选人std::lower_bound
,应致电someFunction(currentArgument)
并将结果与desiredValue
进行比较。 SomeValue
someFunction(x) < someFunction(x + 1)
的确如此。
即。它应该产生与此相同的结果:
int findArgLowerbound(int first, int last, SomeValue refVal){
for (int i = first; i < last; i++){
if (someFunction(i) >= refVal)
return i;
}
return last;
}
仅使用标准函数+二进制搜索算法。
如果有和没有提升,我怎么能 EASILY (没有编写我自己的二进制搜索功能)?
int
不是迭代器,在这种情况下我还没弄明白如何制作boost::make_transform_iterator
。
限制:
- 编辑 -
我想知道如何使用内置或已经可用的函数(std :: lower_bound和类似函数)做我想做的事情。我可以编写专门的二进制搜索功能,但我认为这不是“正确”的方法。
答案 0 :(得分:0)
这就是我接近它的方式:
假装您有一个已排序的vector<SomeValue>
。可以使用someFunction(index)
访问此向量。
现在,look at this。这是二进制搜索的伪代码。继续上述思考过程,将A[imid]
替换为someFunction(imid)
,将key
改为SomeValue
。确保SomeValue
具有有效的operator <
(或您使用的比较器功能代替它)。
这当然只适用于所有someFunction(x) < someFunction(x + 1)
的{{1}}。你说这是真的,所以它应该是好的。
我建议使用迭代方法,因为它们都具有相同的渐近运行时,并且迭代版本可以更容易地报告未找到的密钥,并且倾向于使用更少的内存。
编辑我不知道使用x
内容的简单方法。如上所述,std
不能用作迭代器,并且您可能想要使用的所有函数都使用迭代器。 技术上但是,这些函数中的迭代器是模板化类型,因此您可以编写自己的int
类或类似的东西。使用IntIter
需要std::lower_bound
,operator *()
和operator ++()
。 operator +(int)
可能会返回operator *()
,其中someFunction(n)
是与n
关联的int值。但是, 我不知道这是否真的有效 ,可能需要更多时间和编码。如果你想采用这种方法,你应该看看std::lower_bound
和std::advance
(在IntIter
中调用)。
答案 1 :(得分:0)
想通了(享受宏+模板伏都教)。
#include <boost/iterator/transform_iterator.hpp>
#include <boost/range/irange.hpp>
#include <boost/typeof/std/utility.hpp>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <sstream>
std::string convertArgs(int arg1, int arg2){
std::stringstream out;
out << std::setfill('0') << std::setw(8) << arg1*arg2;
return out.str();
}
void boostTest(){
int first = 0, last = 42;
int arg = 2;
std::string desiredValue = "00000007";
BOOST_AUTO(range, boost::irange(first, last));
BOOST_AUTO(start, boost::make_transform_iterator(range.begin(), std::bind1st(std::ptr_fun(convertArgs), arg)));
BOOST_AUTO(end, boost::make_transform_iterator(range.end(), std::bind1st(std::ptr_fun(convertArgs), arg)));
BOOST_AUTO(found, std::lower_bound(start, end, desiredValue));
if (found != end){
std::cout << "str:" << *found << "\nval: " << *(found.base());
}
}
int main(int argc, char** argv){
boostTest();
return 0;
}
最有可能的是,除非您生成具有所有可能值的数组,否则无法在没有增强的情况下轻松,自己制作包装器迭代器或类似的东西。