recursividad cruzada

Iniciado por fernaEDLP, 12 Enero 2019, 06:57 AM

0 Miembros y 2 Visitantes están viendo este tema.

MAFUS

¿Os ensenan recursividad sin haber pasado todavía por todos los operadores?

Qué curioso.

K-YreX

Cita de: fernaEDLP en 13 Enero 2019, 07:43 AM
Mafus gracias,se nota que sabes programar avanzado pero es demasiado eso para mi, ajaajaj, hace de cuenta que le estas enseñando a un cavernicola, porque  usas sizeof?, y que significa --s?

Aunque ya tengas el tema solucionado, lo importante es resolver las dudas que quedan así que...
- <sizeof()> se usa para obtener el número de bytes que ocupa un tipo de dato. En ese código te devuelve el número de bytes que ocupa un <unsigned long long>.
- <--s> significa decrementar <s> en 1. Al igual que se suele hacer <i++>, se puede hacer también <i-->, <++i> o <--i>. A veces da igual usar el prefijo o el sufijo (cuando es una sentencia aislada, que no va como "encadenada"). El prefijo primero hace el incremento/decremento y después el resto de la sentencia; el sufijo primero hace el resto de la sentencia y al final hace el incremento/decremento.

for(int i = 0; i < 5; i++) // aqui da igual i++ o ++i porque esta solo
    printf("%d", i++); // primero muestra i y luego lo incrementa en 1. Salida: 0, 2, 4

for(int i = 0; i < 5; i++)
    printf("%d", ++i); // incrementa i y luego lo muestra. Salida: 1, 3, 5 (el 5 se muestra aunque la condicion es i < 5)





Cita de: fernaEDLP en 13 Enero 2019, 07:48 AM
tampoco entiendo porque le pasas como parametro n>>1

Si haces <num >> 1> lo que haces es mover los bits de <num> una posición a la derecha. Si tienes:
a = 01011001
a >> 1
a = 00101100
Si el número es negativo se extiende con unos:
a = 11010011
a >> 1
a = 11101001

Como dato interesante que si no te paras a estudiar los bits no te das cuenta es que mover una posición a la izquierda un número en binario es equivalente a multiplicar ese número por 2. Y entonces moverlo una posición a la derecha es equivalente a dividirlo por 2, aunque si es impar se hará obviando los decimales.




Entonces para que entiendas el código ese que la verdad aunque poco efectivo, me parece impresionante:
Usa una función donde manda un <unsigned long long> que es el número a calcular y le pasa como segundo parámetro el número de bits que ocupa un número <unsigned long long> (con <sizeof()> saca el número de bytes y eso por 8, en bits).
Entonces cuando <s == 1> es decir, cuando sólo quede el bit más significativo se retorna ese bit (que valdrá 1 si el número es negativo o 0 si no lo es). Y si <s != 1>, mueve todos los bits una posición a la derecha y decrementa el número de bits que quedan todavía. Algo así en un caso simplificado:
n = 4 (0100) s = 4
s == 1? No -> n = 2 (0010) s = 3
s == 1? No -> n = 1 (0001) s = 2
s == 1? No -> n = 0 (0000) s = 1
s == 1? Si -> return n (return 0)


n = -2 (1110) s = 4
s == 1? No -> n = -1 (1111) s = 3 // los negativos se extienden con 1 para que sigan siendo negativos (cosas del complemento a 2)
s == 1? No -> n = -1 (1111) s = 2
s == 1? No -> n = -1 (1111) s = 1
s == 1? Si -> return n (return 1)




Una función de ese estilo es mejor que no muestre nada por pantalla por si quieres usar esa función dentro de un condicional, sería más funcional entonces sin los <printf()>:

int positivo(int n){
    if(n >= 0)
        return 1;
    else
        return !negativo(n);
}

int negativo(int n){
    if(n < 0)
        return 1;
    else
        return !positivo(n);
}


Espero que esto te ayude a entender y profundizar más en todo lo que se puede hacer con la programación. Suerte :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

fernaEDLP

perdón creo que puse cualquier cosa ahí arriba, ahora creo que esta bien, igual es como muy secillo


void  negativo(int n);
void  positivo(int n);


int main()
{
    int N;
    printf("ingrese el numero\n");
    scanf("%d",&N);
    positivo(N);
    return 0;
}

void positivo(int n)
{
    if(n>=0)
    {
        printf("el numero es positivo\n");
    }
    else
    {
       negativo(n);
    }
}
void  negativo(int n)
{
    if(n<0)
    {
        printf("el numero es negativo\n");
    }
    else
    {
        positivo(n);
    }
}

fernaEDLP

perdon no habia entrado a la segunda pagina

fernaEDLP

Cita de: YreX-DwX en 13 Enero 2019, 11:11 AM
Aunque ya tengas el tema solucionado, lo importante es resolver las dudas que quedan así que...
- <sizeof()> se usa para obtener el número de bytes que ocupa un tipo de dato. En ese código te devuelve el número de bytes que ocupa un <unsigned long long>.
- <--s> significa decrementar <s> en 1. Al igual que se suele hacer <i++>, se puede hacer también <i-->, <++i> o <--i>. A veces da igual usar el prefijo o el sufijo (cuando es una sentencia aislada, que no va como "encadenada"). El prefijo primero hace el incremento/decremento y después el resto de la sentencia; el sufijo primero hace el resto de la sentencia y al final hace el incremento/decremento.

for(int i = 0; i < 5; i++) // aqui da igual i++ o ++i porque esta solo
    printf("%d", i++); // primero muestra i y luego lo incrementa en 1. Salida: 0, 2, 4

for(int i = 0; i < 5; i++)
    printf("%d", ++i); // incrementa i y luego lo muestra. Salida: 1, 3, 5 (el 5 se muestra aunque la condicion es i < 5)





Si haces <num >> 1> lo que haces es mover los bits de <num> una posición a la derecha. Si tienes:
a = 01011001
a >> 1
a = 00101100
Si el número es negativo se extiende con unos:
a = 11010011
a >> 1
a = 11101001

Como dato interesante que si no te paras a estudiar los bits no te das cuenta es que mover una posición a la izquierda un número en binario es equivalente a multiplicar ese número por 2. Y entonces moverlo una posición a la derecha es equivalente a dividirlo por 2, aunque si es impar se hará obviando los decimales.




Entonces para que entiendas el código ese que la verdad aunque poco efectivo, me parece impresionante:
Usa una función donde manda un <unsigned long long> que es el número a calcular y le pasa como segundo parámetro el número de bits que ocupa un número <unsigned long long> (con <sizeof()> saca el número de bytes y eso por 8, en bits).
Entonces cuando <s == 1> es decir, cuando sólo quede el bit más significativo se retorna ese bit (que valdrá 1 si el número es negativo o 0 si no lo es). Y si <s != 1>, mueve todos los bits una posición a la derecha y decrementa el número de bits que quedan todavía. Algo así en un caso simplificado:
n = 4 (0100) s = 4
s == 1? No -> n = 2 (0010) s = 3
s == 1? No -> n = 1 (0001) s = 2
s == 1? No -> n = 0 (0000) s = 1
s == 1? Si -> return n (return 0)


n = -2 (1110) s = 4
s == 1? No -> n = -1 (1111) s = 3 // los negativos se extienden con 1 para que sigan siendo negativos (cosas del complemento a 2)
s == 1? No -> n = -1 (1111) s = 2
s == 1? No -> n = -1 (1111) s = 1
s == 1? Si -> return n (return 1)




Una función de ese estilo es mejor que no muestre nada por pantalla por si quieres usar esa función dentro de un condicional, sería más funcional entonces sin los <printf()>:

int positivo(int n){
    if(n >= 0)
        return 1;
    else
        return !negativo(n);
}

int negativo(int n){
    if(n < 0)
        return 1;
    else
        return !positivo(n);
}


Espero que esto te ayude a entender y profundizar más en todo lo que se puede hacer con la programación. Suerte :-X

graciassss aja!, que lindo paseo me pegaron xD

fernaEDLP

Por favor no se enojen conmigo, tengo una duda que a estas alturas va a ser estupida, pero cuando se retorna un 1 o un 0, dependiendo de si el usuario digita un negativo o un positivo, como te se da cuenta que el numero  es positivo o negativo?¿, no seria mejor que al evaluar la condición dentro del if, cuando chequea que es postivo avise mediante un printf que lo que se ingreso es postivo?, tenganme paciencia pliss :-*

MAFUS

Sí, pero esto es una forma de jugar con el lenguaje. Se prueban diferentes algoritmos sobre problemas de solución sencilla. Divertido, a la par que didáctico. Así cuando surjan problemas reales que necesiten de una solución parecida ya se tendrá experiencia para resolverlo.

fernaEDLP

perfecto gracias a todos!!

K-YreX

Cita de: fernaEDLP en 13 Enero 2019, 20:56 PM
Por favor no se enojen conmigo, tengo una duda que a estas alturas va a ser estupida, pero cuando se retorna un 1 o un 0, dependiendo de si el usuario digita un negativo o un positivo, como te se da cuenta que el numero  es positivo o negativo?¿, no seria mejor que al evaluar la condición dentro del if, cuando chequea que es postivo avise mediante un printf que lo que se ingreso es postivo?, tenganme paciencia pliss :-*

En programación, cuando hay dos posibles respuestas (si/no, verdadero/falso, etc) se traduce a una variable booleana (true/false). Las variables booleanas a veces se interpretan mejor como números (true = 1 / false = 0) y esto sirve para tener un abanico más grande de posibilidades para trabajar por ejemplo con condicionales.

El tema de retornar un 0/1 y no usar un <printf()> es por sencillez. Imagina un programa en el que usas esas funciones que has creado:

int main(){
    // codigo
    if(positivo(n)){
        // codigo
    }
    // codigo
}

Tú necesitas saber si <n> es positivo, pero no hace falta que le avises al usuario. Puede que tengas un programa muy grande donde haces miles de comprobaciones, el usuario no necesita ver cual es el resultado de cada comprobación.

Con el código que te mostré anteriormente puedes aprovechar lo que te he comentado de interpretar 1 = true y 0 = false para usar esas funciones en programas más grandes. Los posibles casos serían:
- n >= 0 -> positivo(n) retorna 1 (true) y negativo(n) retorna 0 (false)
- n < 0 -> positivo(n) retorna 0 (false) y negativo(n) retorna 1 (true)
Por eso por ejemplo en cada función se llama a la otra con el operador de negación(!). Para que los resultados que se obtienen con cada función sean los comentados arriba. Te dejo el código aquí por si quieres comprobarlo:

int positivo(int n){
    if(n >= 0)
        return 1;
    else
        return !negativo(n);
}

int negativo(int n){
    if(n < 0)
        return 1;
    else
        return !positivo(n);
}
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;