1

I'm trying to recursively find a sum of perfect squares in a dynamically allocated list. For some reason, my function keeps overlooking the first element.

*A is the pointer to the first element of the array. n is the number of elements, meaning they are in range from 0 to n-1. When n is less than or equal to zero, n-1 isn't a valid index so I'm returning 0 to the sum of perfect squares.

int sum(int *A, int n)
{
    int i, num = 0;

    if (n <= 0)
        return num;

    for (i = 0; i < A[n - 1]; i++) {
        if (i*i == A[n - 1]) {
            num = A[n - 1];
        }
    }
    return num + sum(A, n - 1);
}

Why does the first element always get overlooked? It works for all the other elements in the list.

EDIT: I've tried calling the function again and it seems that only number 1 got overlooked. That was fixed by modifying the for loop condition, so the solution would be:

int sum(int *A, int n)
{
    int i, num = 0;

    if (n <= 0)
        return num;

    for (i = 0; i <= A[n - 1]; i++) {
        if (i*i == A[n - 1]) {
            num = A[n - 1];
        }
    }
    return num + sum(A, n - 1);
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
randomuser
  • 299
  • 1
  • 4
  • 11

2 Answers2

2

For starters as the array pointed to by A is not changed the pointer should be declared with the qualifier const.

Sizes of objects in C are estimated by using the type size_t. So the second parameter should be declared as having the type size_t.

Also the sum of perfect squares can be larger than an object of the type int can accomodate. So it is better to use the type long long int as the return type.

And if I am not mistaken 0 is not a perfect square. Though it is not very important nevertheless the loop can start with 1 instead of 0..

I can suggest the following solution.

#include <stdio.h>

long long int sum( const int *a, size_t n )
{
    int perfect_square = 0;

    if ( n )
    {
        int i = 1;

        while ( i * i < a[n-1] ) i++;

        if ( a[n-1] == i * i ) perfect_square = a[n-1];
    }

    return n == 0 ? perfect_square : perfect_square + sum( a, n -1 );
}


int main(void) 
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    const size_t N = sizeof( a ) / sizeof( *a );

    printf( "The sum of perfect squares is %lld\n", sum( a, N ) );

    return 0;
}

The program output is

The sum of perfect squares is 14
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I didn't take that into consideration. It isn't that important in this function but if I was supposed to print the perfect squares then yes, 0 would be a mistake! And thank you for providing a better solution. – randomuser Mar 22 '18 at 15:13
1

First element in an array is A[0]. You're returning 0 rather than the value of A[0] when you're calling sum(A,0).

Did you try changing the line to: if (n<=0) return A(0);?

NetJohn
  • 296
  • 1
  • 6
  • It doesn't work, since it just sums the first element with everything else even though it might not be a perfect square (tried it right now). I tried to change the condition from (n<=0) to n(<0) (which made no sense to me), but that didn't work either. The first element for some reason never makes it to the for loop. What I'm returning is num. Num is supposed to store the value of the element if it's a perfect square. If it isn't, it stays 0 and has no effect on the result. – randomuser Mar 22 '18 at 14:41