#c
#c
Вопрос:
У меня есть две структуры, которые имеют значение int для длины числа фибоначчи и самого фибоначчи в целочисленном массиве. Проблема в том, что функция сложения для чисел Фибоначчи (hugeAdd) зависит от интервала длины в структуре фибоначчи. Я могу вызвать ‘malloc’ и поменять местами всю память, необходимую для массива, но при попытке автоматически увеличить переменную length, чтобы сообщить функции добавления (hugeAdd) продолжать добавлять больше целых чисел, я не могу этого понять. Вот список вещей, которые я пробовал.
-
Привязка длины фибоначчи к циклу for, поскольку он был hugeAdd, называется.
-
Проверяю, не больше ли обеих моих цифр Фибоначчи в позиции ‘x’, чем 5, и затем увеличиваю длину.(Это вроде как работает, но я не могу разобраться в его реализации, потому что мне приходится жестко кодировать, какую цифру проверять.)
-
Попытался установить длину фибоначчи в целое число, которое указывает, сколько времени требуется для выполнения цикла.(Работает в течение пары раундов добавления, но затем я получаю ошибку сегмента в моей функции для удаления структур (hugeDestory)).
Есть идеи?
Fibonacci.h(Это заголовочный файл, который содержит struct def и т.д.)
#ifndef __FIBONACCI_H
#define __FIBONACCI_H
typedef struct HugeInteger
{
// a dynamically allocated array to hold the digits of a huge integer
int *digits;
// the number of digits in the huge integer (approx. equal to arraylength)
int length;
} HugeInteger;
// Functional Prototypes
HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q);
HugeInteger *hugeDestroyer(HugeInteger *p);
HugeInteger *parseString(char *str);
HugeInteger *parseInt(unsigned int n);
unsigned int *toUnsignedInt(HugeInteger *p);
HugeInteger *fib(int n);
double difficultyRating(void);
double hoursSpent(void);
#endif
Класс Testcase4.c (Содержит основную функцию и тестовый пример для проверки функции)
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Fibonacci.h"
// print a HugeInteger (followed by a newline character)
void hugePrint(HugeInteger *p)
{
int i;
if (p == NULL || p->digits == NULL)
{
printf("(null pointer)n");
return;
}
for (i = p->length - 1; i >= 0; i--)
printf("%d", p->digits[i]);
printf("n");
}
int main(void)
{
int i;
HugeInteger *p;
for (i = 0; i <= 1000; i )
{
printf("F(%d) = ", i);
hugePrint(p = fib(i));
hugeDestroyer(p);
}
return 0;
}
Класс Fibonacci.c (В этом классе есть все функции для запуска testcase4.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include "Fibonacci.h"
HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q)
{
HugeInteger *hugerInt = malloc(sizeof(HugeInteger));
int overhead=1,i,j,results=0;
int *resultArray = NULL;
if(p == NULL || q == NULL || hugerInt == NULL)
{
return NULL;
}
if(p->length > q->length)
{
resultArray = calloc(((p->length) overhead), sizeof(int));
hugerInt->length = p->length;
hugerInt->digits = malloc(sizeof(int) * (p->length overhead));
if(resultArray == NULL)
{
return NULL;
}
for(int k=0; k < p->length; k )
{
if(k >= q->length)
{
results=p->digits[k]; //check for not skipping smaller int
resultArray[k] = results resultArray[k];
}
else{
results = p->digits[k] q->digits[k];
if(results > 9 )
{
if(p->digits[k 1] == 0)
{
hugerInt->digits[k 1] = 1;
}
resultArray[k 1] = resultArray[k 1] 1;
results = results - 10;
printf("length of resultArray is %dn",p->length 1);
}
resultArray[k] = results;
}
}
}
else
{
resultArray = calloc(((p->length) overhead) 1, sizeof(int));
hugerInt->length = q->length;
hugerInt->digits = malloc(sizeof(int) * (q->length) overhead);
if(resultArray == NULL)
{
return NULL;
}
for(i=0; i < q->length; i )
{
// printf("q length %d", q->length);
if(i >= p->length) // Check if second struct passed is smaller then first one passed
{
results=q->digits[i]; //check for not skipping smaller int
resultArray[i] = results;
}
else{
results = q->digits[i] p->digits[i];
if(results > 9 )
{
printf("I is in larger then 9 check %d", i);
if(p->digits[i 1] == 0)
{
hugerInt->digits[i 1] = 1;
}
printf("i is %dn",i);
printf("Assigning 1 to %d in resultarrayn", i);
resultArray[i 1] = 1; // if value is greater then 9 the 1 carries and gets added to the result.(This is the part i think is going wrong)
results = results - 10;
printf("length of resultArray is %dn",p->length 1);
printf("results:$dn", results);
}
resultArray[i] = results; // Throws added values into array
}
}
}
printf("n=================n");
for(i=0; i < hugerInt->length; i )
{
hugerInt->digits[i] = resultArray[i];
}
free(resultArray);
return hugerInt;
}
HugeInteger *fib(int n)
{
HugeInteger *fibInt = malloc(sizeof(HugeInteger));
HugeInteger *fatherFib = malloc(sizeof(HugeInteger));
HugeInteger *grandfatherFib = malloc(sizeof(HugeInteger));
int j=1,fatherLength=0,grandfatherLength=0,fibLength=0,result, overhead=1;
unsigned int father, grandFather, fib, tempFather, tempGrandfather, tempFib;
fatherFib->digits = calloc((n overhead),sizeof(int) );
fibInt->digits = calloc((n overhead),sizeof(int));
grandfatherFib->digits = calloc((n overhead),sizeof(int) );
fatherFib->length = 1;
grandfatherFib->length = 1;
fibInt->length = 1;
if(n == 0)
{
fibInt->digits[0] = 0;
return fibInt;
}
for(int i=0; i < n; i )
{
if(i >= 1)
{
if(fatherFib->digits[0] >= 5 amp;amp; grandfatherFib->digits[0] >= 5)
{
fibInt->length = 2;
}
else if(fatherFib->digits[1] >= 5 amp;amp; grandfatherFib->digits[1] >= 5)
{
fibInt->length = 3;
}
}
if(i == 0)
{
fatherFib->digits[0]= 0;
grandfatherFib->digits[0]=1;
}
fibInt = hugeAdd(fatherFib,grandfatherFib);
grandfatherFib = fatherFib;
if(fibInt->length == 2)
{
printf("tens value in father fib %dn", fatherFib->digits[1]);
}
fatherFib = fibInt;
}
free(grandfatherFib->digits);
free(grandFatherFib);
return fatherFib;
}
HugeInteger *hugeDestroyer(HugeInteger *p)
{
if(p == NULL)
{
return; // Null check
}
free(p->digits);
free(p->length);
free(p);
return NULL;
}
int power(int base, int numTimes)
{
int result=1,i=0;
if(numTimes == 1)
{
return base;
}
for(;i < numTimes; i )
{
result = result * base;
}
return resu<
}
Комментарии:
1. Вы могли бы рассмотреть возможность использования
malloc
для получения памяти для строки цифр, которая на 1 больше, чем большее из двух предыдущих значений, которые вы хотите добавить, плюс возможный ограничитель. Затем, после добавления,realloc
к фактической необходимой длине. Или не утруждать себя перераспределением из-за такой небольшой разницы.2. @Weather Vane спасибо за предложение, но я сам разобрался. Я смог выяснить, как проверить, прибавляются ли две цифры к 10, и назначить правильную длину.
3. Сумма будет длиннее, чем большее из двух, только если перенос проходит через, но вам нужно полное сложение, чтобы определить это. Например (я знаю, что они не входят в ряд Фибоначчи)
8888888 1111112
сгенерирует перенос, который распространяется из суммы двух буквенных цифр.