Fibonacci使用1个变量

我在接受采访时被问到以下问题:

有没有什么方法可以仅使用1个变量生成Fibonacci系列?

我不知道该回答什么。 我该说什么?

是的,您可以使用封闭forms的表达式 :

哪里

您可以使用double计算表达式并将结果舍入为最接近的整数。 由于浮点运算的精度有限,这个公式将给出足够大的n的错误答案,但我认为它适用于结果适合Java 32位整数的情况。

一点,是的(虽然在C中,你可以将它转换为Java – 它看起来会更加丑陋)。

 #include  #include  int main (void) { unsigned long i = 1; printf ("0\n"); while (((i & 0xffff0000) >> 16) + (i & 0xffff) <= 0xffff) { printf ("%d\n", i & 0xffff); i = ((i & 0xffff) << 16) | ((i >> 16) + (i & 0xffff)); } return 0; } 

产生:

 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 

🙂

当然,真正的问题是:你为什么要这样做?


如果你对它是如何工作感到好奇,那真的很简单。 一个变量实际上分为两部分,这两部分维持Fibonacci序列的各个值。 它在技术上仍然是一个变量,我们只是在它上面施加了一些额外的结构来实现我们的目的。

当然,使用递归:

 public class Test { public static int fib(int n) { return n < 2 ? n : fib(n-1) + fib(n-2); } public static void main(String[] args) { for(int i = 0; i <= 10; i++) { System.out.print(fib(i)+", "); } System.out.println("..."); } } // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ... 

是的,但您仍然需要记住2个值。 您可以使用64位变量并将其用作2个32位变量。

答案是“是”,但也许你可能更具体。

我能想到的第一个例子,使用双递归(导致指数复杂,不推荐):

 int fib(int a) { if (a < 2) { return 1 } else { return fib(a-1) + fib(a-2); } } 

假设a> = 0(你可以添加一个检查)。

(编辑 - 使用错误的F(0)约定未定义,F(1)= 1)

在初始的1 1 ,理论上可以从前一个生成一个值(直到机器精度到来咬你)通过:

 f = Math.round(f * PHI) 

其中PHI是另一个评论中定义的常量:

static final double PHI = (1 + Math.sqrt(5))/2;

你总是可以这样做:

  String theOneVar = "100;0;1"; while (true) { if (theOneVar.split(";")[0].equals("0")) break; System.out.println(theOneVar.split(";")[1]); theOneVar = String.format("%s;%s;%s", Integer.parseInt(theOneVar.split(";")[0]) - 1, theOneVar.split(";")[2], new BigInteger(theOneVar.split(";")[1]).add( new BigInteger(theOneVar.split(";")[2]) ) ); } 

这打印( 如ideone.com上所示 ):

 0 1 1 2 3 5 8 13 : : 83621143489848422977 135301852344706746049 218922995834555169026 

这只使用一个显式变量,它本质上是一个线性非递归算法。 但需要说的是,这是对String的滥用。

所以这是邪恶的,但是:

 static String fibRecord = "x;"; static int nextFib() { try { return fibRecord.indexOf(';'); } finally { fibRecord = fibRecord.replaceAll("(x*);(x*)", "$1$2;$1"); } } public static void main(String[] ignored) { for (int i=0; i < 30; i++) { System.out.println(nextFib()); } } 

我的机器开始在第38个斐波那契数字附近摔倒。

这是C#中的一个例子。 显示前100个术语。 Fibonacci中的项之间的比率接近黄金比率(1.618033 …),因此单个变量方法仅需要乘以每个项的常数。

是的数学!

 double fib = 1; for (int i = 0; i < 100; i++) { Console.WriteLine("" + fib); fib = Math.Round(fib *= 1.6180339887d); } 

该程序最多可打印10个数字,但您可以更改它。

 import java. i o.*; class q { public static void main()throws IO Exception { int n=0; for(int i=1; i<=10 ; i++) { System.out.print(n +" "); n=(int)Math.round(n*1.618) } } } 1.618 = PHI 

程序在导入和主要声明中有一些错误,但正文是完全正确的

 public class test { public static void main(String[] args) { int arr[]=new int[13]; arr[0]=0; arr[1]=1; for(int i=2;i<=12;i++){ arr[i]=arr[i-1]+arr[i-2]; } for(int i=0;i<=arr.length-1;i++){ System.out.print(arr[i]+" "); } } } 
 class fibo{ public static void main (String args[]) { long i = 1; while (((i & 0xffff0000) >> 16) + (i & 0xffff) <= 0xffff) { System.out.println(i & 0xffff); i = ((i & 0xffff) << 16) | ((i >> 16) + (i & 0xffff)); } } } 

这是使用一个变量的斐波那契系列的java代码。