这是我在这里的第一篇文章,所以如果我犯了一些错误,请告诉我。
我已经获得了一项任务,其中一部分需要第n个斐波纳契数的二进制表示。 约束 -
我有一个函数,但它适用于整数。但我必须计算的最大值约为10 ^ 6。所以,我被困在这里。 无论我知道什么,我都无法应用于这种情况,因为我可以产生第n个纤维。使用字符串,但会有线性时间复杂度。 以下是函数,
void multiply(long int F[2][2], long int M[2][2]);
void power(long int F[2][2], long int n);
// Function to Calculate n'th fibonacci in log(n) time
long int fib(long int n)
{
long int F[2][2] = {{1,1},{1,0}};
if(n == 0)
return 0;
power(F, n-1);
return F[0][0];
}
void power(long int F[2][2], long int n)
{
if( n == 0 || n == 1)
return;
long int M[2][2] = {{1,1},{1,0}};
power(F, n/2);
multiply(F, F);
if( n%2 != 0 )
multiply(F, M);
}
void multiply(long int F[2][2], long int M[2][2])
{
long int x = (F[0][0]*M[0][0])%mod + (F[0][1]*M[1][0])%mod;
long int y = (F[0][0]*M[0][1])%mod + (F[0][1]*M[1][1])%mod;
long int z = (F[1][0]*M[0][0])%mod + (F[1][1]*M[1][0])%mod;
long int w = (F[1][0]*M[0][1])%mod + (F[1][1]*M[1][1])%mod;
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
int main(){
int n; cin >> n; cout << fib(n)<<endl; getchar();
}
可以看出,此功能中只能使用预定义的数据类型。
答案 0 :(得分:0)
由于这是作业,我只会给你一些提示。
这两个问题是无关的,所以你需要两种方法:toBinary和fib。 toBinary (fib (n));
将是您的解决方案。
为了解决toBinary部分,除法和模数很有用,可以递归调用。
如果计算fib(n)为fib(n-1)+ fib(n-2),则有一个陷阱进入,当你计算fib(n-1)为fib(n-2)时+ fib(n-3),你最终计算fib(n-2)两次,fib(n-3)三次,依此类推。
相反,你应该从(0 + 1)开始向上步,向前传递已经计算过的。
经过短暂的测试,我看到斐波那契数字的增长速度有多快。您是否可以访问任意大小的Int,或者您是否希望使用预分配的数组?
然后你需要一个add方法,它将较低和较高的数字作为整数或布尔数组,并在较低的数组中创建总和,然后变为上部数组。
既然你已经解决了这个问题,我可以随意发布我的解决方案,以Scala编写:
import annotation._
/**
add two arrays recursively. carry the position pos and the overrun
overrun=0 = 1 0 1 0 1
Sum low | next | Sum
0 1 | overrun | %2
high 0| 0 1 1 2 | 0 0 0 1 | 0 1 1 0
1| 1 2 2 3 | 0 1 1 1 | 1 0 0 1
*/
@tailrec
def add (low: Array[Int], high: Array[Int], pos: Int = 0, overrun: Int = 0): Array[Int] = {
if (pos == higher.size) {
if (overrun == 0) low else sys.error ("overrun!")
} else {
val sum = low (pos) + high (pos) + overrun
low (pos) = (sum % 2)
add (low, high, pos + 1, if (sum > 1) 1 else 0)
}
}
/** call cnt (example: 5) steps of
fib (5, 0, 1),
fib (4, 1, 1),
fib (3, 1, 2),
fib (2, 2, 3),
fib (1, 3, 5),
fib (0, 5, 8) */
@tailrec
def fib (cnt: Int, low: Array[Int], high: Array[Int]): Array[Int] = {
if (cnt == 0) low else fib (cnt - 1, high, add (low, high)) }
/** generate 2 Arrays, size dependent on n of about 0.7*n + 1, big enough to
hold values and result. Result has to be printed in reverse order, from the highest bit
*/
def fibonacci (n: Int) = {
val lower = Array.fill (n * 7 / 10 + 1)(0) // [...000]
val higher = Array.fill (n * 7 / 10 + 1)(0) // [...000]
higher (0) = 1 // [...001]
val res = fib (n, lower, higher)
res.reverse.foreach (print)
println ()
res
}
fibonacci (n)
对于斐波那契(10000),我得到了近7000个二进制数字的结果,并且关系10/7是常数,因此百万分之斐波纳契数字将具有大约1.4M的数字。
答案 1 :(得分:0)
更好的方法是使用Matrix Exponentiation,它将计算n'th fib。在lg(n)时间。 (适用于各种在线编码竞赛)参见This帖子的方法4。