Dos dudas para mejorar el código

Iniciado por DamnSystem, 5 Noviembre 2017, 23:27 PM

0 Miembros y 1 Visitante están viendo este tema.

DamnSystem

Bueno estaba realizando ejercicios y ahora que acabo de terminarlo y antes de seguir con los demás quiero saber como mejorarlo ( voy a mirar la forma de hacerlo con un bucle en vez de tanto if, y la otra duda es cuando meto mas dígitos en el entero de que lo que soporta ejemplo 99999999999999999, el programa ( al menos a mi ) entra en bucle y se queda bloqueado alguna forma de solucionarlo ( no tendría por que hacerlo pero así voy aprendiendo).

Paso código:

//  21. Un número entero n se dice que es desgarrable (torn) si al dividirlo en dos partes
//  cualesquiera izda y dcha, el cuadrado de la suma de ambas partes es igual a n. Por ejemplo,
//  88209 es desgarrable ya que (88 + 209)2 = 88209; 81 también lo es ya que 81 =
//  (8+1)2.Cread un programa que lea un entero ne indique si es ono desgarrable.
//  Finalidad: Ejercitar los bucles. Dificultad Baja.

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    //  Variables y constantes
    int numero_introducido = 0, contador = 1, cifra1 = 0, cifra2 = 0, cifra3 = 0, cifra4 = 0, cifra5 = 0, cifra6 = 0, numero_backup = 0, operado = 0, cifra_total = 0, concatenacion1 = 0, concatenacion2 = 0;
   
    //  Entrada del programa
    do{
    cout << "Introduzca un numero para comprobar si es desgarrable: " << endl;
    cin >> numero_introducido;
    }while(numero_introducido > 999999);
    numero_backup = numero_introducido;
   
    //  Resolucion del programa
    while (numero_introducido / 10 > 0){
        numero_introducido = numero_introducido / 10;
        contador++;
    }
    cout << "Cifras del numero introducido son: " << contador << endl;
    if(contador == 1){
        cout << "El numero no es desgarrable: " << numero_introducido << endl;
    }
    else if (contador == 2){
        //  Con el algoritmo de la division a = b+c + r
        //  Cociente y resto
        cifra1 = numero_backup / 10;
        cifra2 = numero_backup % 10;
        cifra_total = cifra1 + cifra2;
        operado = pow(cifra_total, 2);
        if(numero_backup == operado){
            cout << "El numero: " << numero_backup << " es un numero desgarrable. " << endl;
        }
        else{
            cout << "No es un numero desgarrable" << endl;
        }
    }
    else if (contador == 3){
        cifra1 = numero_backup / 100;
        cifra2 = (numero_backup % 100) / 10;
        cifra3 = numero_backup % 10;
        concatenacion1 = (cifra1 * 10) + cifra2;
        cout << concatenacion1 << endl;
        concatenacion2 = cifra3;
        cout << concatenacion2 << endl;
        cifra_total = concatenacion1 + concatenacion2;
        operado = pow(cifra_total,2);
        if (numero_backup == operado){
            cout << "El numero: " << numero_backup << " es un numero desgarrable. " << endl;
        }
        else{
            cout << "No es un numero desgarrable." << endl;
        }
    }
    else if (contador == 4){
        cifra1 = numero_backup / 1000;
        cifra2 = (numero_backup % 1000) / 100;
        cifra3 = (numero_backup % 100) / 10;
        cifra4 = (numero_backup % 10);
        concatenacion1 = (cifra1 * 10) + cifra2;
        concatenacion2 = (cifra3 * 10) + cifra4;
        cifra_total = (concatenacion1) + (concatenacion2);
        operado = pow(cifra_total, 2);
        if (numero_backup == operado){
            cout << "El numero: " << numero_backup << " es un numero desgarrable. " << endl;
        }
        else{
            cout << "No es un numero desgarrable." << endl;
        }
    }
    else if (contador == 5){
        cifra1 = numero_backup / 10000;
        cifra2 = (numero_backup % 10000) / 1000;
        cifra3 = (numero_backup % 1000) / 100;
        cifra4 = (numero_backup % 100) / 10;
        cifra5 = (numero_backup % 10);
        concatenacion1 = (cifra1 * 10) + cifra2;
        concatenacion2 = (cifra3 * 100) + (cifra4 * 10) + cifra5;
        cifra_total = concatenacion1 + concatenacion2;
        operado = pow(cifra_total, 2);
        if (numero_backup == operado){
            cout << "El numero: " << numero_backup << " es un numero desgarrable. " << endl;
        }
        else{
            cout << "No es un numero desgarrable. " << endl;
        }
    }
    else if (contador == 6){
        cifra1 = numero_backup / 100000;
        cifra2 = (numero_backup % 100000) / 10000;
        cifra3 = (numero_backup % 10000) / 1000;
        cifra4 = (numero_backup % 1000) / 100;
        cifra5 = (numero_backup % 100) / 10;
        cifra6 = (numero_backup % 10);
        concatenacion1 = (cifra1 * 100) + (cifra2 * 10) + cifra3;
        concatenacion2 = (cifra4 * 100) + (cifra5 * 10) + cifra6;
        cifra_total = concatenacion1 + concatenacion2;
        operado = pow(cifra_total, 2);
        if (numero_backup == operado){
            cout << "El numero: " << numero_backup << " es un numero desgarrable. " << endl;
        }
        else{
            cout << "No es un numero desgarrable.  " << endl;
        }
    }
    return 0;
}
<3 Stay Hungry, Stay Foolish <3

ivancea96

Respuesta rápida:
Cuando el número está fuera del rango o no se introduce un número, "cin" pone su flag "fail" a true. Con esta flag a true, cualquier próxima lectura va a fallar (por tanto, no vuelve a pedir input y no sale del while).
Para limpiar esa bandera, basta llamar a "cin.clear();".
Para comprobar si la banderá está puesta, puedes llamar a "cin.fail()" (retorna true si está, false si no).

DamnSystem

Mil gracias voy a probarlo ahora mismo :) y algún consejo para que el código que he puesto sea menos o alguna forma de hacerlo mas eficiente?
<3 Stay Hungry, Stay Foolish <3

Serapis

#3
Como bien se señala, la idea es ejercitar los bucles. Usando bucles, surge la necesidad de usar también arrays o bien variables reutilizables, y no tantas variables para 'componentes individuales'.

La idea es algo así como usar una llave inglesa en vez de 30 llaves fijas de distinto tamaño.

En pseudocodigo de una manera clara, a base de más líneas de código,
podría ser más o menos así (fíjate que las funciones las pongo en orden inverso a como son llamadas, sólo para que veas desde el final hacia el principio):

Esta función, verifica que dados dos valores son o no entre sí desgarrables (en el orden introducido).

Buleano = Funcion EsDesgarrable(entero valor, entero valor1, entero valor2)
   string v1 = ((valor1 + valor2)^2).ToString
 
   devolver (v1 = valor.ToString)
Fin funcion



Esta función toma un valor de entrada y genera para el todos los posibles despieces y con cada uno verifica si cumple lo esperado.

buleano = Funcion DesgarrarValor(entero valor)
   string numeroStr = valor.ToString
   entero digitos = caracteresen(numerostr)
   entero k, n1, n2
   string s1, s2

   bucle para k desde 1 a digitos-1
       s1 = TomarCaracteresDesdeIzquierda(numeroStr, k)
       s2 = TomarCaracteresDesdeDerecha(numeroStr, digitosStr-k)
       n1 = ConvertirAEntero(s1)
       n2 = ConvertirAEntero(s2)
     
       Si EsDesgarrable(valor, n1, n2) = TRUE luego
           devolver TRUE
       fin si    
   fin bucle

   devolver FALSE
fin funcion


La función principal se compone de  1 petición de entrada al usuario (aquí dos, pero puede señalarse un "Introduzca 0 para terminar") y luego una llamada a la función que verifica el asunto y devuelve el resultado, que luego se muestra al usuario... Todo ello encerrado en un bucle hasta que el usuario 'se canse'...

funcion Problema21
   entero numero
   buleano resultado
   string masPreguntas

   Hacer    
         numero = pedirNumeroAlUsuario
         resultado = Desgarrar(numero)
         Si (resultado = TRUE) luego
             mostrarMensaje "El número introducido es desgarrable."
         sino
             mostrarMensaje "el número introducido no es desgarrable."
         fin si

         // en la peición de arriba puede aceptarse un valor 0, como fin de operaciones, en vez de solicitarlo explícitamente aquí.
         masPreguntas = PedirAlUsusario("desea proceder con otro número (s/n) ?."
   Repetir mientras masPreguntas = "s" //"yes", "si", "y", >0, etc....
fin funcion


Como puedes ver, con solo 3 funciones y aún no simplificándolas el código resultante es muy breve. Bastan 2 bucles y unas pocas variables, que incluso podrían ser menos... el caso presente, no precisa ningún array.

Nota que básicamente al desguazar el número hemos operado convirtiendo en número en una cadena de texto, de la que hemos partido en dos trozos (en un bucle, según lo largo del mismo) y luego a conveniencia volver a convertir en número para hacer las operaciones... siempre es más eficiente operar con números que con cadenas, pero el objetivo del ejecrcicio es plantear la solución al problema para operar con bucles, el objetivo aquí no es lograr una eficiencia óptima. ...es importante que entiendas ambas cosas.

Queda a tu esfuerzo convertir el pseudocódigo a C, para lo que te será necesario entenderlo.

p.d.: Nota, que no he considerado el caso de números negativos... la respuesta es buien fácil, pero tú como lo solucionarías?