Split algorithm and conquer the sum of an integer array
I'm having problems with splitting and conquering algorithms and was looking for some help. I am trying to write a sumArray function that calculates the sum of an array of integers.
This function should be done by dividing the array in half and making recursive calls for each half. I tried to use similar concepts to the ones I used when writing recursive sum algorithms and a division and conquest algorithm to determine the maximum element in an array, but I am struggling to combine the two ideas.
Below is the code I wrote for sumArray that compiles but does not return the correct result.
int sumArray(int anArray[], int size)
{
int total = 0;
//base case
if (size == 0)
{
return 0;
}
else if (size == 1)
{
return anArray[0];
}
//divide and conquer
int mid = size / 2;
int lsum = anArray [mid] + sumArray(anArray, --mid);
int rsize = size - mid;
int rsum = anArray[size - mid] + sumArray(anArray + mid, --rsize);
return lsum + rsum;
}
I identified the problem as a function that includes the lsum value when calculating the rsum. I know the problem is my recursive call to sumArray using rsize (a variable that is equal to the size of the original array minus the midpoint). For some reason, however, I cannot find a definition.
It seems to me that I am stupidly asking, since I know that the answer is looking right in my face, but how do I restore my function so that it returns the exact result?
UPDATE: Thanks to all the helpful answers, I've corrected my code so that it compiles and works nicely. I'll leave my original code here in case others struggle with division and win and might make similar mistakes. For a function that correctly solves the problem, see @Laura M. @haris's answer also provides a good explanation of where my code was getting bugs.
source to share
int sumArray(int anArray[], int size)
{
//base case
if (size == 0)
{
return 0;
}
else if (size == 1)
{
return anArray[0];
}
//divide and conquer
int mid = size / 2;
int rsize = size - mid;
int lsum = sumArray(anArray, mid);
int rsum = sumArray(anArray + mid, rsize);
return lsum + rsum;
}
source to share
In your code
int mid = size / 2;
int lsum = anArray [mid] + sumArray(anArray, --mid);
int rsize = size - mid;
int rsum = anArray[size - mid] + sumArray(anArray + mid, --rsize);
allows you to show an example where this makes a mistake.
Let's assume the array is equal { 2, 3, 4, 5, 6, 9}
, sosize = 6
now that yo do mid = size / 2
and then
int lsum = anArray [mid] + sumArray(anArray, --mid);
int rsize = size - mid;
int rsum = anArray[size - mid] + sumArray(anArray + mid, --rsize);
and the mid == (size - mid)
number is 5
added twice (once a lsum
and then a rsum
).
Further, the call sumArray()
to rsum
must have parameters sumArray(anArray + (mid + 1), --rsize)
, since the element mid
has already been added tolsum
In another post, you can find much simpler code for recursion, something like ..
int add(int low,int high,int *a)
{
int mid;
if(high==low)
return a[low];
mid=(low+high)/2;
return add(low,mid,a)+add(mid+1,high,a);
}
source to share
As Haris said, in your code, you add the same number to both the correct amount and the left amount; however, there is a much bigger problem with your code.
You always pass the same array to your recursive calls for lsum and rsum. At first I thought this was just part of your implementation and the size parameter would take care of it. However, the size parameter doesn't work as you may have intended it to work. Your whole algorithm shrinks the size parameter until it reaches 1. Then the base case runs, and as a result, the first element in the original array is returned. What for? You never split an array in your code, and therefore the same array is preserved across all recursive calls (even in the base case).
To fix this problem, all sumarray () should be done is to split the array into left half and right half based on the average calculation and recursively pass this new array until the size of the array is 1 (base case) and you return an element in an array. This effectively splits the array into its individual elements, and all functions should be doing at this point is adding lsum and rsum.
pseudocode:
sumArray(array[]){
if size(array) is 1
return array[0]
mid = size(array) / 2
leftArray = splitArrayUpto(mid, array)
rightArray = splitArrayAfter(mid+1, array)
leftArraySum = sumArray(leftArray)
rightArraySum = sumArray(rightArray)
return leftArraySum + rightArraySum
}
source to share