测试一个数字是否是斐波那契
我知道如何制作斐波纳契数列表,但我不知道如何测试给定的数字是否属于斐波纳契列表 - 想到的一种方法是生成fib列表。 数字到这个数字,看看它是否属于数组,但是必须有另一个更简单快捷的方法。
有任何想法吗 ?
一个非常好的测试是N是一个斐波那契数,当且仅当5 N^2 + 4
或5N^2 – 4
是一个平方数。 有关如何有效测试数字的方法,请参阅SO讨论。
希望这可以帮助
正整数ω是斐波那契数当且仅当5ω2+ 4和5ω2-4中的一个是完美正方形。
查看Faboulous斐波那契数字了解更多。
虽然有几个人指出了完美平方的解决方案,但它涉及到一个斐波纳契数的平方,通常会产生大量的产品。
有少于80个斐波纳契数字,甚至可以保存在一个标准的64位整数。
这是我的解决方案,其运行完全小于要测试的数量。
(用C#编写,使用像double
和long
这样的基本类型,但对于更大的类型,该算法应该可以正常工作。)
static bool IsFib(long T, out long idx)
{
double root5 = Math.Sqrt(5);
double phi = (1 + root5) / 2;
idx = (long)Math.Floor( Math.Log(T*root5) / Math.Log(phi) + 0.5 );
long u = (long)Math.Floor( Math.Pow(phi, idx)/root5 + 0.5);
return (u == T);
}
在我写了这个答案之后的4年多时间里,一位评论者询问了第二个参数,并将其传递
out
。 参数#2是Fibonacci序列中的“Index”。
如果要测试的值是T
是一个斐波那契数,那么idx
将是Fibonacci序列中该数的基于1的索引。 (有一个值得注意的例外)
斐波那契数列是1 1 2 3 5 8 13
等
3是序列中的第4个数字: IsFib(3, out idx);
将返回true
和值4
。
8是序列中的第6个数字: IsFib(8, out idx);
将返回true
和值6
。
13号是第7号; IsFib(13, out idx);
将返回true
和值7
。
唯一的例外是IsFib(1, out idx);
,这将返回2
,即使值1将出现两个索引1和2。
如果IsFib
传递一个非Fibonacci数字,它将返回false
,并且idx
的值将是最大的斐波那契数的索引,小于T
16不是斐波那契值。
IsFib(16, out idx);
将返回false
和值7
。
您可以使用Binet的公式将索引7转换为斐波那契数值13,这是最大数量小于16的数字。