[英]Optimize a algorithm that find a specific Fibonacci number
Given an number A , I want to find the Ath Fibonacci number that is multiple of 3 or if the number representation has at least a 3 on it.
给定数字A ,我想找到3的倍数的Ath斐波那契数,或者如果数字表示形式上至少有3的话。
Example: 例:
Fibonacci > 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...
斐波那契> 0、1、1、2、3、5、8、13、21、34、55、89、144、233,...
Input: 1, Output: 3;
输入:1,输出:3;
3 is the first Fibonacci number that is multiple of 3 or has an 3 on it.
3是第一个斐波那契数,它是3的倍数或上面有3的数字。
Input: 3, Output: 21;
输入:3,输出:21;
21 is the third Fibonacci number that is multiple of 3 or has an 3 on it.
21是第三个斐波那契数,它是3的倍数或上面有3的数字。
Edit: Variable type changed to unsigned long long int and ajust on Fibonacci generator. 编辑:变量类型更改为unsigned long long int,并且在Fibonacci生成器上为ajust。 Thanks @rcgldr and @Jarod42 for the help!
感谢@rcgldr和@ Jarod42的帮助!
My code: 我的代码:
#include<bits/stdc++.h>
using namespace std;
int tem(unsigned long long int i){
while(i != 0){
if(i%10 == 3){
return true;
}
i = i/10;
}
return false;
}
int main(){
int a, count = 0;
unsigned long long int f1 = 1, f2 = 1;
while(scanf("%d", &a) != EOF){
for(unsigned long long int i = 2; i > 0; i++){
i = f1 + f2;
f1 = f2;
f2 = i;
if((i%3 == 0) || tem(i)){
count++;
if(count == a){
cout << i << endl;
break;
}
}
}
}
}
When A > 20, it starts to slow down. 当A> 20时,它开始变慢。 Makes sense because it tends to be exponecial.
很有道理,因为它倾向于指数级。 My code is not very efficient, but I didn't find an better logic to use.
我的代码效率不是很高,但是我没有找到更好的逻辑。
I looked into these links, but didn't find an conclusion: 我调查了这些链接,但没有得出结论:
1 - Recursive Fibonacci 1- 递归斐波那契
2 - Fibonacci Optimization 2- 斐波那契优化
Any ideas? 有任何想法吗? Thanks for the help!
谢谢您的帮助!
You can speed up the Fibonacci part using this sequence 您可以按照以下顺序加快斐波那契零件的速度
uint64_t f0 = 0; // fib( 0)
uint64_t f1 = 1; // fib(-1)
int n = ... ; // generate fib(n)
for(int i = 0; i < n; i++){
std::swap(f0,f1);
f0 += f1;
}
Note Fib(93) is the maximum Fibonacci number that fits in a 64 bit unsigned integer, it also has a 3 in it. 注意Fib(93)是适合64位无符号整数的最大斐波那契数,其中也有3。 Fib(92) is the maximum Fibonacci number that is a multiple of 3.
Fib(92)是最大斐波那契数,是3的倍数。
I used this example code to find all of the values ( a
ranges from 0 to 62), it seems to run fairly fast, so I'm not sure what the issue is. 我用这个例子的代码来找到所有的值(
a
范围为0〜62),它似乎运行速度相当之快,所以我不知道是什么问题。 Is optimization enabled? 是否启用优化?
#include <iostream>
#include <iomanip>
typedef unsigned long long uint64_t;
int tem(uint64_t i){
while(i != 0){
if(i%10 == 3)
return true;
i = i/10;
}
return false;
}
int main(){
int a = 0, n;
uint64_t f0 = 1, f1 = -1; // fib(-1), fib(-2)
for(n = 0; n <= 93; n++){
std::swap(f0, f1); // f0 = next fib
f0 += f1;
if((n&3) == 0 || tem(f0)){
std::cout << std::setw( 2) << a << " "
<< std::setw( 2) << n << " "
<< std::setw(20) << f0 << std::endl;
a++;
}
}
return 0;
}
Depending on the compiler, i%10 and i/10 may use a multiply by "magic number" and shift to replace divide by a constant. 根据编译器的不同,i%10和i / 10可能会使用乘以“幻数”并将其移位以用常数替换除数。 Code generated by Visual Studio 2015 for tem(), which is fairly "clever":
由Visual Studio 2015为tem()生成的代码,该代码相当“聪明”:
tem proc ;rcx = input
test rcx,rcx ; return false if rcx == 0
je SHORT tem1
mov r8, 0cccccccccccccccdh ;magic number for divide by 10
tem0: mov rax, r8 ;rax = magic number
mul rcx ;rdx = quotient << 3
shr rdx, 3 ;rdx = quotient
lea rax, QWORD PTR [rdx+rdx*4] ;rax = quotient*5
add rax, rax ;rax = quotient*10
sub rcx, rax ;rcx -= quotient * 10 == rcx % 10
cmp rcx, 3 ;br if rcx % 10 == 3
je SHORT tem2
mov rcx, rdx ;rcx = quotient (rcx /= 10)
test rdx, rdx ;loop if quotient != 0
jne SHORT tem0
tem1: xor eax, eax ;return false
ret 0
tem2: mov eax, 1 ;return true
ret 0
tem endp
Just pointing out some obvious coding errors 只是指出一些明显的编码错误
for(unsigned long long int i = 2; i > 0; i++)
is redundant. 是多余的。
for(;;){
unsigned long long i = f1+f2;
should suffice. 应该足够了。 Secondly
其次
return 0;
is meaningless because it breaks out of the while loop. 是没有意义的,因为它打破了while循环。 A
break
would be better. break
会更好。
There's a clever way to do Fibonacci. 有一种做斐波那契的聪明方法。
http://stsievert.com/blog/2015/01/31/the-mysterious-eigenvalue/ http://stsievert.com/blog/2015/01/31/the-mysterious-eigenvalue/
Code's in python and is just for the nth number, but I think you get the idea. 代码在python中,仅用于第n个数字,但我想您明白了。
def fib(n):
lambda1 = (1 + sqrt(5))/2
lambda2 = (1 - sqrt(5))/2
return (lambda1**n - lambda2**n) / sqrt(5)
def fib_approx(n)
# for practical range, percent error < 10^-6
return 1.618034**n / sqrt(5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.