Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-04-2017
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 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
  #2  
Antiguo 30-04-2017
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Lo ultimo lo he podido solucionar y he reducido algo mas el codigo pero me gustaria hacerlo lo mas cortito posible y que funcione bien:
Código PHP:
#include <iostream.h>
#include <iomanip.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 " << setprecision(2) << fixed << 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 ObtenerStringInt(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;

    for(
int i=0i<N_DIGITOS_ENTEROi++){
        
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[3][0];
                }
                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: case MILLARES:
                            
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
                            
if(i==MILLARES){
                                
salida += " ";
                                
salida += cadenas[0][1];
                            }
                            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
                                    
if(digitos[i+1] != 0)
                                        
salida += cadenaDecenas[digitos[i+1]-1];
                                    else
                                        
salida += cadenas[2][digitos[i]];
                                    if(
i==DECENAS){
                                        
i++;
                                        continue;
                                    }
                                    
salida += cadenas[0][1];
                                    
i++;
                                    break;
                                case 
2//Si es 2 uso la cadena oportuna para las veintenas compuestas
                                    
if(digitos[i+1] != 0)
                                        
salida += "veinti";
                                    else{
                                        
salida += cadenas[2][digitos[i]];
                                        if(
i==DECENAS_MILLAR){
                                            
salida += cadenas[0][1];
                                            
i++;
                                        }
                                    }
                                    break;
                                default:
                                    
salida += cadenas[2][digitos[i]]; //Inserto la cadena correspondiente
                                    
if(digitos[i+1] != 0)
                                        
salida += "y ";
                                    else if(
i==DECENAS_MILLAR)
                                        
salida += cadenas[0][1];
                            }
                            break;

                        case 
CENTENAS: case CENTENAS_MILLAR//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[1][digitos[i]]; //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: case MILLARES:
                            
salida += cadenas[3][digitos[i]]; //Inserto la cadena correspondiente
                            
if(i==MILLARES){
                                
salida += " ";
                                
salida += cadenas[0][1]; //Inserto la cadena que le corresponda
                            
}
                            break;

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

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

    }
    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=ObtenerStringInt(parteEntera,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 << "y " << parteDecimal << "/100"<< endl;

    
cout << "Pulsa intro para salir...";
    
pausar();
    return 
0;
}
//--------------------------------------------------------------------------- 
Responder Con Cita
  #3  
Antiguo 02-05-2017
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
En el FTP del Club busca el componente ATexto en la sección Delphi|Componentes. Ese componente hace la conversión de números a letras. Quizá te sirva para comparar los códigos o usarlo.

LineComment Saludos
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
alguien puede convertir esta funcion a C++ Builder ? Snaked C++ Builder 5 26-10-2016 23:08:01
Alternativas a esta funcion JuanOrtega Varios 4 14-07-2013 21:25:47
¿Una función en Delphi, puede devolver varios parámetros? socger Varios 6 27-02-2009 18:00:07
una aplicacion puede actuar como funcion ?? arequipa2000 Varios 4 12-02-2009 16:03:16
Se Puede Hacer Esta Consulta ? Renees Conexión con bases de datos 0 26-04-2006 18:32:32


La franja horaria es GMT +2. Ahora son las 20:43:13.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi