c - 结构体中的结构体数组中的 int 数组

标签 c arrays struct fibonacci memoization

我希望我不会在这个网站上受到打击。我是一名新手程序员,对这个概念有很多困难。我的任务是记住斐波那契数列。我认为我已经掌握了一个概念,但当然实现指南如下,这让我感到困惑。

typedef struct Memo
{
// dynamically allocated HugeInteger array to store our Fibonacci numbers
struct HugeInteger *F;

// the current length (i.e., capacity) of this array
int length;
} Memo;

typedef struct HugeInteger
{
// a dynamically allocated array to hold the digits of a huge integer
int *digits;

// the length of the array (i.e., number of digits in the huge integer)
int length;
} HugeInteger;

正如您所看到的,斐波那契数不会是简单的“int”,而是存储在 int 数组中的数字,例如 int - 134528 将位于这样的数组中 int someNumber[6] = {1,3,4,5,2,8}

我已经像这样创建了备忘录:

Memo *createMemo(void)
{
/*
Description: Create and initialize a Memo struct:
1. Dynamically allocate space for a new Memo struct.

2. Within the Memo struct, dynamically allocate an array of INIT_MEMO_SIZE number of
HugeInteger structs. INIT_MEMO_SIZE is defined in Fibonacci.h.

Note: This is an array of actual structs, not pointers to structs. So, you cannot set     the
individual elements of this array to NULL, and you cannot free() them.

3. Once the array is created, initialize memo→length appropriately.

4. Make two calls to HugeInit() to initialize F[0] and F[1] (your two Fibonacci base
cases) within the Memo struct.

5. For all remaining F[i], initialize the digits field to NULL and the length field to 0     to
indicate that F[i] has not yet been memoized.

Panic: If any calls to malloc() fail within this function, call panic() (defined in
HugeInteger.c) with the following string argument: “ERROR: out of memory in
createMemo()\n”.

Returns: A pointer to the new Memo struct.
*/
int i;

//Dynamically allocate new Memo
Memo *newMemo = malloc(sizeof(Memo));

        //Check if malloc failed
        if(newMemo == NULL)
            panic("ERROR: out of memory in createMemo()\n");

//Malloc a newMemo->F struct
newMemo->F = malloc(sizeof(HugeInteger *) * INIT_MEMO_SIZE);

        //Check if malloc failed
        if(newMemo->F == NULL)
            panic("ERROR: out of memory in createMemo()\n");

//Initialize the length of the Memo
newMemo->length = INIT_MEMO_SIZE;

//Make two calls to HugeInit to initialize F[0] and F[1] base cases
HugeInit(&newMemo->F[0], 0);
HugeInit(&newMemo->F[1], 1);

//Initialize the rest of F[i] to NULL & length to 0 so I now it's not memoized
for(i=2; i<INIT_MEMO_SIZE; i++)
    {
    newMemo->F[i].digits = NULL;
    newMemo->F[i].length = 0;
    }

//Return the newly created Memo
return newMemo;
}

创建新的备忘录后,我现在进入斐波那契函数,这就是我的大脑失败的地方。我像这样实现了斐波那契函数: struct HugeInteger *fib(int n, Memo *memo)

{
/*
Description:
Implement a recursive solution that checks whether F(n) has already been memoized and,     if so,
returns F(n) without making any recursive calls. 

1. If n exceeds the bounds of the array in memo, call expandMemo(). For more information
on what parameters to pass to expandMemo(), refer to its function description above.

3. In order to compute and memoize F(n), you must call the HugeAdd() function that is
defined in HugeInteger.c. The function requires F(n - 1) and F(n - 2) to be memoized
already. HugeAdd() will memoize F(n) if you call it correctly (i.e., it will store the     result
in memo).

Returns: The address of the struct within memo that holds F(n). If memo is NULL or n is     less than
0, return NULL without performing any recursive calls and without calling expandMemo().
*/
int i;

//Handle for negative numbers
if(n < 0 || memo == NULL)
    return NULL;

//Handle for index out of bounds
if(n > memo->length)
    expandMemo(memo, n);

//Check Memory if F[n] already exists and return it
if(memo->F[n].digits != NULL)
    return &memo->F[n];

//return the base cases;
if(n < 2)
    return &memo->F[n];
else
{
    //My thought process was to make two recursive calls and then use the provided
 HugeAdd function to add the information together. HOWEVER the HugeAdd function is a 
void function so it does it's thing and returns nothing. basically it takes the two
arrays and adds them index by index like you would on paper. 
The first argument of Huge add is the first HugeInteger to be added, then the second 
argument is the second HugeInteger to be added, and the third argument is the
HugeInteger where you want the result. second problem I see is that temp1 is never
being malloc'd or initialized so as the fibonacci series grows temp1 will need to be
malloc'd accordingly and then it will need to be filled accordingly. I am lost 
completely as to how to implement this. 

    HugeInteger *temp1 = fib(n-1, memo);
    HugeInteger *temp2 = fib(n-2, memo);

    HugeAdd(&temp1, &temp2, &memo->F[n]);
}

return &memo->F[n];

}

我完全不知道如何将斐波那契数放入各自的数组槽中,然后将它们推送到 HugeAdd 函数。我概述的功能无法更改,我只能创建辅助功能来提供帮助。

我只是想要洞察力,我知道我必须像其他人一样独自穿越编程 hell 的深处,我只需要一点指导,这样我就可以停止一次 6 小时编写垃圾代码,却一事无成。

最佳答案

正如我在评论中指出的,您应该首先尝试使用 HugeInteger 的 stub 实现来调试程序。一旦您确信斐波那契例程的逻辑正常工作,您就可以尝试集成真正的 HugeInteger 实现。为了帮助您开始,这里有一个简单的 stub :

typedef struct HugeInteger {
    unsigned long long digits;
    int length;
} HugeInteger;

void HugeInit (HugeInteger *h, unsigned long long val) {
    h->digits = val;
    h->length = 1;
}

void HugeAdd (const HugeInteger *a, const HugeInteger *b, HugeInteger *c) {
    assert(a->length);
    assert(b->length);
    assert(!c->length);
    c->digits = a->digits + b->digits;
    c->length = 1;
}

void HugePrint (const HugeInteger *a) {
    assert(a->length);
    printf("%llu\n", a->digits);
}

另一个指针。在您的 createMemo() 例程中,您没有正确分配 F 数组:

//Malloc a newMemo->F struct
newMemo->F = malloc(sizeof(HugeInteger *) * INIT_MEMO_SIZE);

MemoF 成员是一个 HugeInteger *,因此,您想要分配 sizeof(HugeInteger) * INIT_MEMO_SIZE 相反。

关于c - 结构体中的结构体数组中的 int 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17055824/

相关文章:

javascript - a = [未定义] 和 a = new Array(1) 之间的区别

arrays - Swift 中 Array 的 removeLast() 和 popLast() 方法有什么区别?

go - 从函数类型获取结构

c - 如何中断阻塞 IO 的后台线程?

c - 如何在不放弃 const 的情况下实现 strstr()?

c - 如何终止 C 语言中的 system() 调用

c - 尝试读取文件时出现段错误?

c++ - 你能制作一个接受 C++ 中的 vector 和数组的模板吗?

具有非连续布局的 C 位域元素

python - 在 python 中创建 C/C++ 类结构对象的最佳方法是什么?