以下代码将使用adjacent_difference算法生成前10个Fibonacci数:
v = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
std::adjacent_difference(v.begin(), v.end() - 1, v.begin() + 1, std::plus<int>());
for (auto n : v) {
std::cout << n << ' ';
}
std::cout << '\n';
输出:1 1 2 3 5 8 13 21 34 55
但是如果我想继续生成Fibonacci数,直到达到(比如说)4,000,000(例如不是第四百万个Fibonacci数,而不是第N个Fibonacci数,其值恰好是400万(或更高) ))。
显然,带有push_back的while循环可以完成这项工作,但我想知道是否可以将STL算法与back_inserter和lambda函数结合起来指定重复直到条件(例如,在值400万之后停止插入是达到或超过)?
我看到的问题是大多数算法都在一个范围内运行,并且提前我们不知道需要多少元素才能生成400万的Fibonacci数。
答案 0 :(得分:5)
标准算法用于提取编程实践中常见的实现。这使您更容易理解代码和读者理解它。使用内置算法将fibonnacci数累积到给定值对于您和读取代码的人来说都是一种过度杀伤。
为您的用例编写一个“哑”解决方案非常简单,并且更易于维护。例如:
void fibUpTo(int limit) {
int a, b, c;
a = b = 1;
while (a < limit) {
cout << a << endl;
c = a + b;
a = b;
b = c;
}
}
答案 1 :(得分:3)
int my_plus(int a, int b)
{
int result = a + b;
if (result >= 4000000)
throw result;
return result;
}
try {
adjacent_difference(v.begin(), v.end() - 1, v.begin() + 1, my_plus);
} catch (int final) {
cout << final << endl;
}
这就是我认为的“愚蠢的黑客”,但我认为它会起作用。如果你想稍微提高一点,可以创建一个异常类来保存最终结果,而不是抛出一个原始整数。并将阈值设为模板参数。
但实际上,不要做任何这样的事情,因为这是一个愚蠢的黑客:只是使用你提到的“for”循环。
答案 2 :(得分:2)
使用find_if
和来自boost iterator lib的一些帮助:
#include <boost/iterator/function_input_iterator.hpp>
#include <algorithm>
#include <climits>
struct fibonacci_generator {
typedef int result_type;
fibonacci_generator() : n(0) {}
// dummy generator
// put the code to generate fibonacci
// sequence here
int operator()() { return n++; }
private:
int n;
};
int main()
{
fibonacci_generator g;
int i = *std::find_if(
make_function_input_iterator(g, boost::infinite()),
make_function_input_iterator(g, boost::infinite()),
[](int i) { return i > 1000000; });
}
此处copy_until
算法可用于将结果推回到矢量,但您需要编写自己的算法。