STL算法生成斐波纳契数直到达到某个值

时间:2013-10-15 12:33:19

标签: c++ stl

以下代码将使用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数。

3 个答案:

答案 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算法可用于将结果推回到矢量,但您需要编写自己的算法。