斐波那契数位-计算斐波那契数位

时间:2019-12-08 22:35:45

标签: c fibonacci

我需要找到直到1000位的斐波那契数位。

例如:1代表1位数字,10代表2位数字,100代表3位数字...

斐波那契数列以此方式开始:0,1,2,3,5,8,13 ...

我必须插入1000并得到4782。

我将看到4781插入524,如下所示。我想插入1000并得到4782。有什么可能的方法来获取堆栈的长度?在python中,我可以使用len函数,在C中,它将不起作用:)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int s) {
    int i = 1;
    int k = 1;
    int list[1000] = { 0, 1 };
    int fibo = 0;
    int s = -1;
    int divide = 0;
    while (i < 1500) {
        i++;
        fibo = list[i - 1] + list[i - 2];
        if (i == 1000) {
            break;
        } else {
            list[i] = fibo;
            //printf("%d\n", list[i]);
        }
    }

    while (s < 524) {
        s++;
        divide = 0;
        while (list[s] != 0) {
            divide = list[s] / 10;
            list[s] = divide;
            k++;
            if(divide == 0) {
                break;
            }
        } 
    }
    printf("%d\n", k);
}

2 个答案:

答案 0 :(得分:1)

这是一个使用近似的快捷方式实现,即使对于很小的数字也能很好地发挥作用:

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    int n;
    if (argc > 1) {
        n = strtol(argv[1], NULL, 0);
    } else {
        if (scanf("%d", &n) != 1)
            return 1;
    }
    double phi = (1.0 + sqrt(5.0)) / 2.0;
    printf("%g\n", ceil(n / log10(phi) - 3.0));
    return 0;
}

phi是黄金分割率。斐波那契数列非常迅速地收敛到黄金比例的几何序列。换句话说,fib(n)大约为pow(phi, n - 3)。将这个方程式反演10 i 即可得出解决方案。

答案 1 :(得分:0)

这个简单的问题在C语言中比在Python中解决要困难得多:与Python不同,C语言在默认情况下不具有多精度整数算术,因此您必须自己实现(至少要加法),最好是在基数10中实现。

这是一个快速而幼稚的实现:

#include <stdio.h>
#include <stdlib.h>

typedef struct bignum {
    int len;
    unsigned char *digits;
} bignum;

void bignum_init(bignum *a, int v) {
    a->len = 1;
    a->digits = malloc(1);
    if (a->digits == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    a->digits[0] = (unsigned char)v;
}

void bignum_free(bignum *a) {
    free(a->digits);
    a->digits = NULL;
    a->len = 0;
}

void bignum_print(const bignum *a) {
    int i = a->len;
    while (i-- > 0)
        putchar('0' + a->digits[i]);
}

void bignum_add(bignum *c, const bignum *a, const bignum *b) {
    int i, aux;

    if (a->len < b->len) {
        const bignum *tmp = a;
        a = b;
        b = tmp;
    }
    c->digits = realloc(c->digits, a->len + 1);
    if (c->digits == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    for (i = 0, aux = 0; i < b->len; i++) {
        aux += a->digits[i] + b->digits[i];
        c->digits[i] = aux % 10;
        aux /= 10;
    }
    for (; i < a->len; i++) {
        aux += a->digits[i];
        c->digits[i] = aux % 10;
        aux /= 10;
    }
    if (aux != 0) {
        c->digits[i++] = (unsigned char)aux;
    }
    c->len = i;
}

int main(int argc, char *argv[]) {
    int i, n;

    if (argc > 1) {
        n = strtol(argv[1], NULL, 0);
    } else {
        if (scanf("%d", &n) != 1)
            return 1;
    }
    bignum B[3];
    bignum_init(&B[0], 0);
    bignum_init(&B[1], 1);
    bignum_init(&B[2], 1);
    for (i = 3;; i++) {
        bignum_add(&B[i % 3], &B[(i - 1) % 3], &B[(i - 2) % 3]);
        if (B[i % 3].len >= n)
            break;
    }
    printf("%d\n", i);
    // for debugging
    //printf("fib(%d) = ", i);
    //bignum_print(&B[i % 3]);
    //printf("\n");
    bignum_free(&B[0]);
    bignum_free(&B[1]);
    bignum_free(&B[2]);
    return 0;
}