Recursivity in C

0

I honestly do not understand why this code does not work, if someone can give me a hand, it has very few lines; the slogan is a vector, where the sequence has to be strictly increasing , that is, an array: 3, 5, 7 - > meets the condition; and an array: 5, 2, 4 - > DO NOT meet the condition .

I have the following code:

#include <stdio.h>
#define TAM 50

typedef enum tBool{falso, verdadero} _tBool;

_tBool creciente(int v[TAM], int n, int i, _tBool fFlag);

int main(int argc, char const *argv[]){
    /* code */
    int vec[TAM];
    int i, n;
    _tBool c, mFlag;

    printf("Ingrese cantidad de elementos del vector: "); scanf("%d", &n);
    for(i= 0; i<n; i+=1){
        printf("Ingrese elemento %d: ", i); scanf("%d", &vec[i]);
    }

    c= creciente(vec, n, 0, mFlag);
    if(c) printf("La sucesion es creciente\n");
    else printf("La sucesion NO es creciente\n");

return 0;

}

_tBool creciente(int v[TAM], int n, int i, _tBool fFlag){
    if(i<n){
        if(v[i+1]>v[i]) return creciente(v, n, i+1, fFlag= verdadero);
        else return creciente(v, n, i+1, fFlag= falso);
    }else return fFlag;

}

/*
v, n= 3; el0= 2; el1=4; el3= 6;
creciente(v, 3, 0, fFlag)= creciente(v, 3, 1, verdadero); 
creciente(v, 3, 1, verdadero)= creciente(v, 3, 2, verdadero);
creciente(v, 3, 2, verdadero)= creciente(v, 3, 3, verdadero);
creciente(v, 3, 3, verdadero)= verdadero;
*/
    
asked by Fesa 06.04.2016 в 11:35
source

2 answers

3
typedef enum tBool{falso, verdadero} _tBool;

C has an alias already created for Boolean types. You can find it in the stdbool.h library, which is available from the C99 standard, which dates back to 1999.

_tBool creciente(int v[TAM], int n, int i, _tBool fFlag){
    if(i<n){
        if(v[i+1]>v[i]) return creciente(v, n, i+1, fFlag= verdadero);
        else return creciente(v, n, i+1, fFlag= falso);
    }else return fFlag;
}

We are going to analyze this function in parts:

if(v[i+1]>v[i]) if the only thing you are checking is i<n , what guarantee do you have that i+1<n ? none, then you will read outside the memory of the arrangement.

return creciente(v, n, i+1, fFlag= falso);

If you already know that the condition is not going to be fulfilled, you do not need to go through the arrangement ... return a false directly and save yourself the rest of the process.

This solution you apply has an additional problem. Suppose a vector such that 1,2,1,2 . Finding the second 1 will be called creciente(false) . This call will check that 1<2 and call creciente(true) ... as we have reached the end of the vector that true is the one that will be finally returned which is clearly incorrect.

So, as you could see, it's best not to complicate your life. If you know that a condition is not going to be fulfilled, you do not have to continue checking because you already have the answer.

_tBool creciente(int v[TAM], int n, int i)
{
  if(i+1<n)
  {
    if(v[i+1]>v[i]) return creciente(v, n, i+1); // De momento se cumple...
    else return falso; // No se cumple la condición
  }
  else return verdadero; // Hemos llegado al final, luego el vector es creciente
}

Greetings.

    
answered by 06.04.2016 / 11:46
source
1

Another possible solution would be:

t_bool creciente(int *v, int n){

     if(n == 0)
        return verdadero;
     if(v[n] >= v[n-1])
        return creciente(v, n - 1);
     else
        return falso;
}

esCreciente = creciente(v, n - 1);

Explaining a bit: The function receives the vector and size, and runs it from highest to lowest. If it is in the first position it is because it has already compared all the elements, then it is increasing; otherwise, compare the current elements v [n] > = v [n-1], if that condition is true, the function is called with the following elements to be increased (v, n - 1). In case it is not fulfilled, it will no longer be growing and will return false.

    
answered by 09.01.2017 в 08:34