Создание функции Фибоначчи и не может правильно добавить добавить / представить целые числа две цифры или больше - PullRequest
0 голосов
/ 17 марта 2019

Это программа для сложения чисел Фибоначчи.Рассматриваемая функция огромнаДобавить.Целые числа правильно добавляют к 8, однако, как только он достигает 13 или выше, он возвращает неправильное значение.Неправильное значение, являющееся адресом памяти для переноса (1), но правильное значение для позиции единиц (3).Попытка установить его вручную, однако, кажется, не работает по какой-то причине, потому что 'k' моя переменная-счетчик, объявленная в операторе for, не может быть вызвана даже внутри цикла for.

Примечание: вот самый маленький MCVE, который я мог сделать.Создайте точку останова в строке 134 в файле Fibonacci.c, и он выведет добавленные целые числа.

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));
    //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 %d\n",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 %d\n",i);
      printf("Assigning 1 to %d in resultarray\n", 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 %d\n",p->length+1);
      printf("results:$d\n", results);
  }


      resultArray[i] = results; // Throws added values into array


    }
  }
}

printf("\n=================\n");
for(i=0; i < hugerInt->length; i++)
{
   hugerInt->digits[i] = resultArray[i];
}


printf("Result array at 0 is %d\n", resultArray[0]); // This is were the 
printf("Result array at 1 is %d\n", resultArray[1]); // added numbers are stored.
printf("Result array at 2 is %d\n", resultArray[2]);

printf("=====================\n");

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 && grandfatherFib->digits[0] >= 5)
  {
  fibInt->length = 2;

  }
  else if(fatherFib->digits[1] >= 5 && 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 %d\n", fatherFib->digits[1]);
}
fatherFib = fibInt;


}
 free(grandfatherFib->digits);
 free(grandFatherFib);
 return fatherFib;

}


int power(int base, int numTimes)
{
int result=1,i=0;

if(numTimes == 1)
{
    return base;
}

for(;i < numTimes; i++)
{
    result = result * base;
}
return result;
}

1 Ответ

2 голосов
/ 17 марта 2019

С учетом предупреждений / ошибок при компиляции кода: (до выпуска вопроса)

в Fibonacci.c

else if(strlen(str) == 0 && str[0] == "")

str[0] - это char , str[0] == "" никогда не соответствует действительности, просто сделайте

else if (str[0] == 0)

In

HugeInteger *hugeDestroyer(HugeInteger *p)
{

   int length;

  // printf("Hiiting destroyer");
   if(p == NULL)
   {
       return;
   }

   length = p->length;

    free(p->digits); // But this works???????

    free(p->length);
    free(p);

 }

, вы никогда не вернетезначение (указатель на HugeInteger ), видимо оно должно иметь подпись void hugeDestroyer(HugeInteger *p) (также в заголовке)

В

free(p->length);

Вы освобождаете int ?

, удаляете эту строку, а также другие бесполезные строки длиной

так что наконец

void hugeDestroyer(HugeInteger *p)
{
  // printf("Hiiting destroyer");
  if (p != NULL)
  {
    free(p->digits); // But this works???????
    free(p);
 }
}

В

     unsigned long long int check = malloc(sizeof(unsigned long long int));

malloc вернуть адрес (указатель), и фактически вы не используете check (check = nextPow + real isтакже бесполезно)

сложно представить, что вы хотели сделать, убрать все о проверить

в

 if(p->digits[k+1] == NULL)
 ...
 if(p->digits[i+1] == NULL)

p->digits[k+1] - это int , вы сравниваете с указателем, замените NULL на 0

В

hugePrint(fibInt);

неизвестно, отсутствует его объявление

Когда вы компилируете запрос высокого предупреждения / ошибки уровень обнаружения иисправьте ваш код в соответствии


Относительно утечек памяти:

В огромный * Добавить

HugeInteger *test = malloc(sizeof(HugeInteger));
test->length= 1;
test->digits = malloc(sizeof(int));
test->digits[0] = 5;

test никогда не используется после этого, вы просто создаете утечку meomry

 resultArray = calloc(((p->length)+ overhead), sizeof(int));

вы устанавливаете его содержимое, но никогда не освобождаете его, этодругая утечка памяти

В fib

HugeInteger *grandfatherFib = malloc(sizeof(HugeInteger));

вы никогда не освободитесь grandfatherFib это другая утечка памяти


Относительно результата:

  • fib (0) = 0: ok
  • fib (1) = 1: ok
  • fib (2) = 2: нормально
  • ...
  • fib (6) = 8: нормально
  • fib (7) = 13: нормально
  • fib (8) = 11: k

Ваша проблема в том, что вы плохо добавляете числа по крайней мере из 2 цифр, например, если я изменяюнемного конец огромное добавление для замены

 printf("Result array at 0 is %d\n", resultArray[0]); // This is were the 
 printf("Result array at 1 is %d\n", resultArray[1]); // added numbers are stored.
 printf("Result array at 2 is %d\n", resultArray[2]);
 printf("=====================\n");

более практичным

printf("=====================\n");
hugePrint(p);
puts("+");
hugePrint(q);
puts("=");
hugePrint(hugerInt);
printf("=====================\n");

и я делаю fib(8), что показывает:

...
=====================
08
+
5
=
13
=====================
13
tens value in father fib 0
I is in larger then 9 check 0i is 0
Assigning 1 to 0 in resultarray
length of resultArray is 3
results:1

=================
=====================
13
+
08
=
11
=====================

вы пропустили добавить перенос: 8 + 3 = 11 так 1 и перенос 1 добавить к 1 , чтобы 21 вместо 11

, чтобы

if(results > 9 )
{
  printf("I is in larger then 9 check %d", i);
  if(p->digits[i+1] == 0)
  {
    hugerInt->digits[i+1] = 1;
  }

недостаточно, потому чтозначение carry должно быть добавлено , не равно 1, если значение 0 (больше нет, только 0 становится 1).Конечно, вам, возможно, придется учесть несколько изменений, добавив перенос от 1 до 999, вы получите 1000

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...