Solving problems recursively in C - c

Our professor gave us the following assignment:
A "correct" series is one in which the sum of its members equals to the index of its first member.
The program is supposed to find the length of the LONGEST "correct" series within a series of n numbers.
For example: if the input series would be arr[4]={1, 1, 0, 0}
the output (longest "correct" series) would be 3.
arr[0]=1. 0!=1 therefore the longest series here is 0.
arr[1]=1,and 1=1. but the following members also sum up to 1 as shown below:
1=arr[1]+arr[2]+arr[3] = 1+ 0 + 0, therefore the longest series here is 3.
The output in this example is 3.
This is what I have so far:
int solve(int arr[], int index, int length,int sum_so_far)
{
int maxwith,maxwithout;
if(index==length)
return 0;
maxwith = 1+ solve(arr,index+1,length,sum_so_far+arr[index]);
maxwithout = solve(arr,index+1,length,arr[index+1]);
if(sum_so_far+arr[index]==index)
if(maxwith>maxwithout)
return maxwith;
return maxwithout;
return 0;
}
int longestIndex(int arr[], int index,int length)
{
return solve(arr,0,length,0);
}
What am I doing wrong here?
We aren't supposed to us loops on this assignment.

Hmm, there are several problems with this program.
Most obvious, "return maxwithout; return 0;" should give a compile error: There's no way to get to that last return statement.
Second, you're recursing in to solve on the "maxwith" path until you reach the end of the array. Then you're going to recurse into maxwithout, hitting it for the first time with index=4. I don't think this is going to work.
Frankly, I don't think this problem really calls for recursion. THe most natural solution would be a nested loop:
for (int start=0;start<length;++start)
{
for (int end=start;end<length;++end)
{
// calculate the sum of arr[start]->arr[end] and compare to start
}
}
Or something to that effect.
Did the problem call for solving it with recursion, or was that just your first idea at a good solution?
Edit
Okay, so you have to use recursion. I guess the point of the lesson is to learn to use recursion, not necessarily to solve the problem in the most natural or efficient way. (Personally, I think the teacher should have come up with a problem where recursion was a natural solution, but I guess we're not here to critique the teacher today.)
I don't want to do your homework for you, but I'll give you a hint. You can use recursion to simulate a loop by putting the break condition at the beginning of the function and putting the recursive call at the end of the function with a +1 parameter. That is, instead of writing
for (int x=0;x<10;++x) { ... whatever ...}
you can write
void forx(int x)
{
if (x>=10)
return;
... whatever ...
forx(x+1);
}
So in this case I'd do something like:
void endloop(int start, int end)
{
if (end>=arrayLength)
return;
... work on running total ...
endloop(start, end+1);
}
void startloop(int start)
{
if (start>=arrayLength)
return;
endloop(start, start);
}
int main()
{
... setup ...
startloop(0);
... output ...
}
Parameter lists are not necessarily complete. As I say, I don't want to do your homework for you, just give you a hint to get started.

First, write a function that tests a series of given starting index and given length for the "sum of its members" condition. Then, write a second function which looks for the longest series within your array where only the starting index is given (looping over the sub-series length in decreasing order should do it); this function can call the first one. At last, write a third function looping over all starting indexes, calling function number two.
Oh wait, there is no recursion needed any more, so a lot of brain-twisting is gone ... :-)

It seems to me that the problem lies here:
if(sum_so_far+arr[index]==index)
You're comparing the sum so far with the current index, but you should be comparing it with the first index in the series. It seems to me that it would be better if you started with the last element of arr towards the first, instead of going in the natural order. That way you start summing elements up until the sum equals the current index.

Related

Does Ruby create a copy when referencing an array with its [..] (slice) method?

I want to loop on a slice of an array. I have basically two main options.
ar.each_with_index{|e,i|
next if i < start_ind
break if i > end_ind
foo(e)
#maybe more code...
}
Another option, which I think is more elegant, would be to run:
ar[start_ind..end_ind].each{|e|
foo(e)
#maybe more code...
}
My concern is Ruby potentially creating a huge array under the hood and doing a lot of memory allocation. Or is there something "smarter" at play that does not create a copy?
You could do a loop of index values... not as elegant as your second solution but economical.
(start_ind..end_ind).each do |index|
foo(ar[index])
# maybe more code
end
You may want to refer to methods' C source code, but it takes a bit of time to read the code. May I help you in this
First: each_index
It's source code in C is tricky, but boils down to something similar to 'each' which looks like
VALUE rb_ary_each(VALUE ary) {
long i;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
for (i=0; i<RARRAY_LEN(ary); i++) {
rb_yield(RARRAY_AREF(ary, i));
}
return ary;
}
It does not create any other array internally by itself. What it effectively does is it simply loops through elements, takes each element and passes it into the block provided (rb_yield part). What's actually inside the block that you provide is a different story.
Second: [...].each
You actually have to notice it is two function calls. The second being 'each' is of little interest to us since it is described above The first function call is '[]'. Logically you expect it to output an subarray as variable, which has to be stored at least temporary.
Let's verify. Source code for C is rather long, but the piece of the greatest importance to you is:
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary) {
// some code
if (argc == 2) {
beg = NUM2LONG(argv[0]);
len = NUM2LONG(argv[1]);
if (beg < 0) {
beg += RARRAY_LEN(ary);
}
return rb_ary_subseq(ary, beg, len);
}
// some more code
}
It's actually for a function call like ar[start_ind, end_ind] and not ar[start_ind..end_ind]. The difference is immaterial, but this way is easier to understand.
The thing that answers your question is called "rb_ary_subseq". As you may guess from its name or learn from its source, it actually does create a new array. So it would create a copy under the hood of size equal or less of the array given.
You'd want to consider computational cost of functional calls, but the question is about memory.

Counting the times numbers occur in an array using (count_numbers(int [], int, int)) C

So what I have is an array that's size is decided by me and then the elements in the array are randomly generated. It's supposed to take an integer array,its size, and an integer number
and find how many times the number is present in the array and return that count at the end.I keep trying stuff and nothing seems to be getting me anywhere close to an answer. I was just trying to see if someone could point me in the right direction on where to start
count_numbers(int array[], int size, int z)
Hhave you tried running a loop through the array and trying a match expression to the array value in another loop. This seems like a logic question rather than actual code related. Maybe a search around the internet looking at how to count in arrays could help you.
This should point you in the right direction...
for (int i = 0; i < arraySize; i++) {
if (array[i] == z /*z being your search value**/) {
you may have to alter this a little
//dosomething
// e.g. increment a count here
}
else
do-nothing essentially.
There is a method for checking array size - so don't worry about defining it's size. have a look at the java method for this and use it.
Hope this helps

equality testing in for loops

I'm currently writing a program to calculate arctangent using a Taylor Series sum. The centre part of the code is the following:
for(int i=0;i<n;i++)
{
firstval=sum; //sum=0
sum=sum+sumterm(x,i); //calculate the sum
if(fabs(sum-firstval)<delta) //delta=10e-6
{
s=i;
}
else s=0;
}
How I think this code is working: 'sum' is initialised to 0, meaning that 'firstval' is as well. The program then calculates the Taylor series value for a particular value of i, and adds it on to the sum. Then, as 'sum' and 'firstval' are different, the magnitude of their difference can be calculated - as the loop proceeds, firstval is the previous value of the sum, and then in the loop, sum becomes its next term. Then when the difference between them is sufficiently small, and the condition is matched, the value of i for which that has happened is saved to an integer s, which is otherwise 0.
However, the program currently only produces 0, or says that the sum has only converged at n-1. I've spent quite a while playing around with different configurations of the code and can't work out why it's doing what it is. I'm still a newbie to this programming thing, so any help is welcome. Sorry if this post is unclear, I know that I haven't included the rest of the program, but I've had a quite long and tiring day. Thanks :)
You may want to use a while loop instead. The condition to exit the while loop could be:
while (fabs(sum-firstval)>delta)
Otherwise, other suggestions (using a break after variable s has been assigned value of i) work too.

Sub-array of integers with given sum, using recursion in C

I have got a pretty hard task I find difficult to handle.
I'm trying to write a recursive function (no loops at all) that, given an array and its length, will print a pair of sub arrays, each of which's sum will be half of the sum of the entire array. In other words, the array is to be divided into two groups of integers so that their sum is equal.
For example, given the array {1,2,2,0,5}, the function should output {1,2,2} {0,5}
I have to do it recursively, with a function that gets only the array itself and its size. I am also only allowed to use one more additional recursive function to solve the problem.
Any thoughts or ideas will be most appreciated.
Hello again!
we got a code in class that goes like this
int SubsetSum(int arr[], int idx, int n, int S) {
if (S==0) return 1; //This is stopping condition #1.
if (S<0 || n==0) return 0; //This is stopping condition #2.
return SubsetSum(arr, idx+1, n-1, S-arr[idx]) || SubsetSum(arr, idx+1, n-1, S);
}
what does the " || " operator means in terms of recursion?
thanks ppl!
You first calculate the sum of the whole array (it'll better be even), and this gives you the half-sum, which you can reach using a binary knapsack routine.
There is also a recursive implementation on Stack Overflow in Java, which isn't too different from C and satisfies your requirements.
Divide the array and sub-arrays from the middle until there is only one element.
Compare the first element with second and find sum of these integers.
After that use these sums for binary elements comparing. When doing this compare find the sum. For example your sub-arrays are {1,2} and {0,3}. Look the first elements 0 and 1. When you see the little element take the other element in that sub-array ( {0,3} ). After that sum is now 3. The other part's sum is 1 and take the other element (2). Now the sum is 3 for both. And you can use this for all sub-arrays.
I'm not sure about the solution. But I think it seems like divide-and-conquer algorithm.

Algorithm to find maximum sum of elements array such that not more than k elements are adjacent

Hi,
I came across this question. Given an array containing only positive values. You need to find the maximum sum that could result by adding the elements. The condition is that you cannot pick more than k adjacent elements. My simple solution is this
http://pastebin.com/s4KxjQRN
This solution does not produce correct input in all cases. I am not able to figure out why.
Can any one help? Thank you.
In your code, you just skip on every k+1th element. Sometimes, it's better to skip on more elements, but do it wisely. (choose the lowest numbers to skip on, etc)
Edit: some simple recursive solution: (it's not effective, but will work)
long maxsum(int n,int k,long *profits) {
long sum=0,max=0,cur;
int i;
if (n<=k) {
for (i=0;i<n;i++) sum+=profits[i];
return sum;
}
for (i=0;i<=k;i++) {
cur=sum+maxsum(n-i-1,k,profits+i+1);
if (cur>max) max=cur;
sum+=profits[i];
}
return max;
}

Resources