1

I have to write a recursive function that counts how many times a short array s2 is present in a bigger array s1 without overlapping. I'm allowed to use more than one function that can help me but they have to be all recursive function. For example:

#define n 10
#define p 2

s1[n]={0,2,3,23,54,1,8,23,54,1}
s2[p]={23,54}
OUTPUT: 2 (we see s2 two times in s1)

I thought about writing a recursive function that tells me if there is at least one occurence then use this function in another recursive function that counts the number of occurences. So this is what I wrote:

//Initially pos1=0 and pos2=0

int find(int *s1,int *s2,int pos1,int pos2){
if(n-pos1<p-pos2)
    return 0;

if(*(s1+pos1)==*(s2+pos2)){
    if(pos2==p-1)
        return pos1;
    else{
        if(find(s1,s2,pos1+1,pos2+1))
            return pos1;
    }
}
return find(s1,s2,pos1+1,0);
}

Then I wrote the second recursive function that is supposed to count the number of occurences:

 // Initially occ(s1,s2,0);
 int occ(int *s1,int *s2,int memo){
    if(memo==n){ //end of s1
        return 0;
    }
    else{
        if(find(s1+memo,s2,memo,0))
    return 1+occ(s1+memo,s2,memo+p);
    }
}

The idea behind it is to verify if there is at least one occurence if there is an occurence then count it and redo the verification for the remaining part of s1 until the end.

The problem is that the code of the second function doesn't work at all and I can't find a way to fix it.

So how can I write a second recursive function that COUNTS the number of occurences using the function find() written above?

Dipok
  • 181
  • 9
  • Why the code of the second function doesn't work at all did you try to debug it ? – fedi Jul 10 '16 at 10:25
  • Yes I tried many times and failed every times, the code that I posted is my final result. I don't know why it fails – Dipok Jul 10 '16 at 10:27
  • It works if s1[n]={0,0,0,3,4,0,0,0,3,4,0,0,0,3,4,0,0,0,3,4}; and s2[p]={3,4}. Indeed the output is 4. But if s2[p]={0,0} the output is 0 which is not correct. – Dipok Jul 10 '16 at 10:30
  • when using the code you mention above and print the result of the function fine : `printf("%d",find(s1,s2,0,0));` i get 3 as a result, are you sure you post your last version ? – fedi Jul 10 '16 at 10:55
  • 1
    Yes I did not write anything else, however the final result is given by occ() , the function find is supposed to return the position of the first occurence. – Dipok Jul 10 '16 at 10:57
  • @fedi there 3 is not the no of occurrences instead it's the position of first occurrence – Cherubim Jul 10 '16 at 10:57
  • @Dipok initially do you send `occ(s1,s2,0)` this way? – Cherubim Jul 10 '16 at 10:59
  • Yes! I forgot to write it here – Dipok Jul 10 '16 at 11:03
  • It's a bit hard for me to get why you need _two_ functions, both of which have to be _recursive_, when you can easily solve it in a single _non-recursive_ function. Is it an exercise in recursion? – user3078414 Jul 10 '16 at 11:08
  • Yes it is text from an exam of my course so I have to solve it recursively. – Dipok Jul 10 '16 at 11:15

1 Answers1

1

From the OP's comment

It works if s1[n]={0,0,0,3,4,0,0,0,3,4,0,0,0,3,4,0,0,0,3,4}; and s2[p]={3,4}. Indeed the output is 4. But if s2[p]={0,0} the output is 0 which is not correct.

  • This is because, when s2={0,0} the find() function returns pos1 = 0 as the subset is present at the very beginning and thus in occ() function if(find(s1+memo,s2,memo,0)) evaluates to be false and terminates the function without returning any value and this invokes undefined behavior

  • This can be avoided by returning any number other than 0 but it must not be the any valid position value in the array s1.

  • Since position cannot be negative number, I've chosen -1


See the following code to know how to avoid it :

#include <stdio.h>

#define n 10
#define p 2

int s1[n]={0,2,3,23,54,1,8,23,54,1};
int s2[p]={23,54};

//find function
int find(int* s1,int* s2,int pos) //only used `pos` instead of `pos1`, removed `pos2`
{
    if(pos > n-2)
    {
        return -1; //returns `-1` upon reaching the end of the code
    }

    if(*(s1+pos) == *(s2+0)) //check at `s1+pos`
    {
        if(*(s1+(pos+1)) == *(s2+1)) //check next element `s1+pos+1`
        {
            return pos; //if both true return `pos`
        }

        else
        {
            return find(s1,s2,pos+1); //else recursively find in the rest of the array
        }
    }

    return find(s1,s2,pos+1); // recursively find in the rest of the array
}


//occurence function    
int occ(int *s1, int *s2,int memo)
{
    if(memo == -1) //if end of the array, end adding occurrences by returning 0 
    {
        return 0;
    }

    else
    {
        memo = find(s1, s2, memo); //scan position into memo

        if(memo != -1) //if not end of the array i.e, `-1` add to occurrence
        {
            return 1+occ(s1,s2,memo+2);
        }

        else
        {
            return 0; //else return 0 and recursion would end in next call as memo is -1
        }
    }
}

//main function
int main(void)
{
    printf("%d",occ(s1,s2,0)); //just to see the output
} 
  • output :

    2 //true as {23,54} occur two times
    
  • when input is : (compile time)

    #define n 20
    #define p 2
    
    s1[n]={0,0,0,3,4,0,0,0,3,4,0,0,0,3,4,0,0,0,3,4};
    s2[p]={0,0};
    
  • output :

    4 //true as {0,0} occurs at 0,5,10,16
    

Community
  • 1
  • 1
Cherubim
  • 5,287
  • 3
  • 20
  • 37
  • 1
    I didn't even think about the fact that if(find(s1+memo,s2,memo,0)) was false in that case! I was focusing too much on finding a good way to count the occurences. Great! – Dipok Jul 10 '16 at 14:07
  • 1
    @Dipok are you fine with the changes that I've done to the functions? if you have any doubts then feel free to ask me – Cherubim Jul 10 '16 at 14:22
  • 1
    Yes I'm fine but maybe the function *find()* would be more generic if it has also pos2 so that we can make the program more flexible, for example we can have *s2[]* with 5 or 7 elements instead of just two. But your solution is totally fine according to what the exercise ask us to do :) @Cherubim Anand – Dipok Jul 10 '16 at 14:35