Ver Mensaje Individual
  #1  
Antiguo 30-04-2017
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Reputación: 11
aguml Va por buen camino
¿Se puede simplificar esta funcion?

Hola amigos, me he creado una aplicacion que le introduces un numero entre 0 y 999999 y lo convierte en una cadena de texto. La verdad es que la parte que lo pasa a texto me he liado y he acabado haciendo todo con switch y condicionales y me gustaria ver como simplificarlo para no usar tantos. Aqui el codigo:
Código PHP:
#include <iostream.h>
#include <limits>

#define LIMITE_SUP 999999.99
#define LIMITE_INF 0
#define N_DIGITOS_ENTERO 6
#define UNIDADES 5
#define DECENAS 4
#define CENTENAS 3
#define MILLARES 2
#define DECENAS_MILLAR 1
#define CENTENAS_MILLAR 0

using namespace std;

void pausar()
{
    
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
cin.get();
}

double SolicitarNumero(void)
{
    
double num;

    
//Pido un valor dentro del rango valido
    
do{
        
cout << "Introduce un numero (" << LIMITE_INF << " a " << LIMITE_SUP << "): ";
        
cin >> num;
        if(
num LIMITE_INF || num >= LIMITE_SUP)
            
cout << "El numero introducido excede del rango valido. Vuelva a intentarlo." << endl;
    }while(
num LIMITE_INF || num >= LIMITE_SUP);

    return 
num;
}

string ObtenerString(double numint digitos[N_DIGITOS_ENTERO])
{
    
//Cadenas constantes
    
char cadenas[4][11][15]={{"","mil ","dosmil ","tresmil ","cuatromil ","cincomil ","seismil ","sietemil ","ochomil ","nuevemil "},
                             {
"","cien ","doscientos ","trescientos ","cuatrocientos ","quinientos ","seiscientos ","setecientos ","ochocientos ","novecientos "},
                             {
"","diez ","veinte ","treinta ","cuarenta ","cincuenta ","sesenta ","setenta ","ochenta ","noventa "},
                             {
"cero","uno","dos","tres","cuatro","cinco","seis","siete","ocho","nueve"}};
    
char cadenaDecenas[9][15]={"once","doce","trece","catorce","quince","dieciseis","diecisiete","dieciocho","diecinueve"};

    
string salida;
    
bool termina=false;

    for(
int i=0i<N_DIGITOS_ENTERO && !terminai++){
        
bool compuesta=false;
        switch(
digitos[i]){
            case 
0//Si es un cero no hacemos nada excepto que sea la unidad y el resto de posiciones tambien sea cero
                
if(i==N_DIGITOS_ENTERO-1){
                    for(
int j=0;j<N_DIGITOS_ENTERO;j++){ //Busco para saber si hay algun digito diferente de 0
                        
if(digitos[j] != 0){
                            
compuesta=true;
                            break;
                        }
                    }
                    if(!
compuesta//Si no hay ningun digito diferente de 0 coloco 'cero' en la cadena de salida
                        
salida += cadenas[i][digitos[i]];
                }
                break;
            default: 
//Si no es cero el digito
                
for(int j=i+1;j<N_DIGITOS_ENTERO;j++){ //Busco si despues de dicho digito hay algun digito diferente de 0
                    
if(digitos[j] != 0){
                        
compuesta=true;
                        break;
                    }
                }
                if(
compuesta){ //Si existe algun digito diferente de 0 detras de en el que estoy ahora...
                    
switch(i){
                        case 
UNIDADES:
                            
salida += cadenas[i][digitos[i]]; //Inserto la cadena correspondiente
                            
break;
                        case 
DECENAS: case DECENAS_MILLAR//Si la decena es 2 uso la cadena "veinti" para crear una cadena compuesta
                            
switch(digitos[i]){
                                case 
1//Si es 1 uso las cadenas oportunas para las decenas compuestas
                                    
salida += cadenaDecenas[digitos[i+1]-1];
                                    if(
i==DECENAS){
                                        
termina=true;
                                    }else if(
i==DECENAS_MILLAR){
                                        
salida += cadenas[0][digitos[1]];
                                        
i++;
                                    }
                                    break;
                                case 
2//Si es 2 uso la cadena oportuna para las veintenas compuestas
                                    
salida += "veinti";
                                    break;
                                default:
                                    if(
i==DECENAS_MILLAR)
                                        
salida += cadenas[2][digitos[i]];
                                    else
                                        
salida += cadenas[2][digitos[i]]; //Inserto la cadena correspondiente

                                    
if(i==DECENAS || i==DECENAS_MILLAR//Si es las decenas coloco la cadena "y "
                                        
salida += "y ";
                            }
                            break;

                        case 
CENTENAS//Si es 1 y no son las unidades cojo del segundo array de cadenas para crear una cadena compuesta
                            
if(digitos[i]==1)
                                
salida += "ciento ";
                            else
                                
salida += cadenas[i-2][digitos[i]]; //Inserto la cadena correspondiente
                            
break;

                        case 
MILLARES:
                            
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
                            
salida += " ";
                            
salida += cadenas[0][1];
                            break;

                        case 
CENTENAS_MILLAR:
                            if(
digitos[i]==1){
                                
salida += "ciento ";
                            }else{
                                
salida += cadenas[3][digitos[i]];
                                
salida += "cientos "//Inserto la cadena correspondiente
                            
}
                            break;

                        default: 
//Para cualquier otro valor
                            
salida += cadenas[i][digitos[i]]; //Inserto la cadena correspondiente
                    
}
                }else{ 
//Si no existe ningun digito diferente de 0 detras del actual
                    
switch(i){
                        case 
UNIDADES:
                            
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
                            
break;

                        case 
DECENAS:
                            
salida += cadenas[2][digitos[i]]; //Inserto la cadena correspondiente
                            
break;

                        case 
CENTENAS:
                            
salida += cadenas[1][digitos[i]]; //Inserto la cadena correspondiente
                            
break;

                        case 
DECENAS_MILLAR:
                            
salida += cadenas[2][digitos[i]]; //Inserto la cadena correspondiente
                            
salida += cadenas[0][1];
                            break;

                        case 
CENTENAS_MILLAR:
                            
salida += cadenas[1][digitos[i]]; //Inserto la cadena correspondiente
                            
salida += cadenas[0][1];
                            break;

                        case 
MILLARES:
                            
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
                            
salida += " ";
                            
salida += cadenas[0][1]; //Inserto la cadena que le corresponda
                    
}
                }
        }

    }
    return 
salida;
}

void SepararDigitos(int numint digitos[N_DIGITOS_ENTERO])
{
    for(
int i=N_DIGITOS_ENTERO-1i>=0i--,num /=10)
        
digitos[i]=num%10;
}

int main(int argccharargv[])
{
    
int parteEntera,parteDecimal;
    
double num;
    
string salida;
    
int digitos[N_DIGITOS_ENTERO];

    
num=SolicitarNumero();

    
//Separo la parte entera y la parte decimal truncando la decimal y quedandome solo con dos decimales
    
parteEntera num;
    
parteDecimal = (num-parteEntera)*100;

    
//Separo los digitos enteros
    
SepararDigitos(parteEntera,digitos);

    
//Concateno la cadena a partir de sus digitos
    
salida=ObtenerString(num,digitos);

    
//En caso de añadir una parte a la cadena la cual tiene un espacio detras y luego no añadir nada despues
    //nos dejaria con una cadena terminada con un espacio asi que solo añado un espacio cuando esta no acabe
    //ya en espacio
    
if(salida[salida.length()-1]!= ' ')
        
salida += " ";

    
//Añado la cadena de la parte decimal
    
cout << salida << parteDecimal << "/100"<< endl;

    
cout << "Pulsa intro para salir...";
    
pausar();
    return 
0;
}
//--------------------------------------------------------------------------- 
Otra cosa ¿como hago para que cuando solicito el numero no me muestre el limite superior en notacion cientifica? quiero que lo muestre tal cual lo tengo definido pero no doy con la forma.
Y un ultimo fallo que tiene el codigo es que si meto 999999.99 me muestra "novecientos noventa y nueve mil novecientos noventa y nueve y 98/100" deveria mostrar "novecientos noventa y nueve mil novecientos noventa y nueve y 99/100" ¿porque le resta uno a la parte decimal al extraerlo? ¿como corrijo eso?

Última edición por aguml fecha: 30-04-2017 a las 14:33:57.
Responder Con Cita