Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: david_BS en 6 Mayo 2012, 21:34 pm



Título: Convertidor de número literal a número real
Publicado por: david_BS en 6 Mayo 2012, 21:34 pm
Hola, había observado en el foro que un usuario había preguntado sobre como hacer algo así, y otros usuarios le dieron ciertas ideas..
Entonces decidí tratar de hacerlo ya que me había parecido algo complicado, y logré buenos resultados. pero estoy seguro que faltan validaciones y muchos otros casos para que el programa interprete y pueda realizar la conversión.

Entonces voy a postear el programa funcionando para algunos casos, pero como ya dije no puede estar completo ya que si ingresan una cadena de un número literal grande entonces no va a interpretarla.

El objetivo es mostrar la idea, y por supuesto si alguien quiere postear su propia idea o mejorar mi código, bienvenido

Dejo el project en VS6.0 para descargarlo (http://www.mediafire.com/?9ubvo9vs3so6o5r)

A continuación describo un poco el code,

Estas son las estructuras de datos (matrices char o vector de string) en donde guardo ciertas cadenas con nombres particulares.. me refiero a nombres de números o nombres los cuales pueden combinarse y significar un número.

Código:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// UTN FRGP TSP
// 2012
// BS
// david_bs@live.com
// Etalking.Com.Ar
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <stdio.h>

char otros[100][30] = {

"cero",
"X",
"X",
"X",
"X",
"X",
"X",
"X",
"X",
"X",
"X",
"once",
"doce",
"trece",
"catorce",
"quince",
"dieciseis",
"diecisiete",
"dieciocho",
"diecinueve",
"X",
"veintiuno",
"veintidos",
"veintitres",
"veinticuatro",
"veinticinco",
"veintiseis",
"veintisiete",
"veintiocho",
"veintinueve",
"X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X",
"X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X",
"X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X","X",
"X","X","X","X","X","X","X"
};

char especiales[][30] = {

"veintiun",
"ciento",
"millon"
"billon"
"millones",
"billones"
};

char cadenas1[][30] = {

"uno",
"un",
"diez",
"cien",
"mil",
};

char cadenas2[][30] = {

"dos",
"veinte",
"doscientos",
};

char cadenas3[][30] = {

"tres",
"treinta",
"trescientos",
};

char cadenas4[][30] = {

"cuatro",
"cuarenta",
"cuatrocientos",
};

char cadenas5[][30] = {

"cinco",
"cincuenta",
"quinientos",
};

char cadenas6[][30] = {

"seis",
"sesenta",
"seiscientos",
};

char cadenas7[][30] = {

"siete",
"sententa",
"setecientos",
};

char cadenas8[][30] = {

"ocho",
"ochenta",
"ochocientos",
};

char cadenas9[][30] = {

"nueve",
"noventa",
"novecientos",
};

Luego una función auxiliar que no viene al caso explicar..
Código:
unsigned int DivisionesDeVector(unsigned int* vec, unsigned int veclen){

unsigned int c=0;
for(unsigned int i=0; i<veclen; i++){

if(vec[i]>0) c++;
}
return c;
}


Esta función si es importante porque recibe la cadena ingresada por partes, y las va interpretando.. parece que tiene muchos fores pero son pequeños XD
Código:
unsigned int Equivalencia(const char* str){

unsigned int len = strlen(str);
char str_test[30];
memset(str_test,0,sizeof(str_test));
strcpy(str_test,str);

if(!strcmpi(str, "veintiun")){

return 21;
}

if(!strcmpi(str, "ciento")){

return 100;
}

if(!strcmpi(str, "millon")){
return 1000000;
}

if(!strcmpi(str, "billon")){
return -1;
}

if(!strcmpi(str, "millones")){
return 1000000;
}

if(!strcmpi(str, "billones")){
return -1;
}

{
for(unsigned int i=0; i<100;i++)
{
if(otros[i][0]!='X')
if(!strcmpi(str_test, otros[i])){
return i;
}
}
}

{
for(unsigned int i=0; i<5;i++)
{
if(!strcmpi(str_test, cadenas1[i])){
if(i==0) return 1;
if(i==1) return 1;
if(i==2) return 10;
if(i==3) return 100;
if(i==4) return 1000;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas2[i])){
if(i==0) return 2;
if(i==1) return 20;
if(i==2) return 200;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas3[i])){
if(i==0) return 3;
if(i==1) return 30;
if(i==2) return 300;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas4[i])){
if(i==0) return 4;
if(i==1) return 40;
if(i==2) return 400;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas5[i])){
if(i==0) return 5;
if(i==1) return 50;
if(i==2) return 500;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas6[i])){
if(i==0) return 6;
if(i==1) return 60;
if(i==2) return 600;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas7[i])){
if(i==0) return 7;
if(i==1) return 70;
if(i==2) return 700;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas8[i])){
if(i==0) return 8;
if(i==1) return 80;
if(i==2) return 800;
}
}
}

{
for(unsigned int i=0; i<3;i++)
{
if(!strcmpi(str_test, cadenas9[i])){
if(i==0) return 9;
if(i==1) return 90;
if(i==2) return 900;
}
}
}

return -1;
}

El main es largo y lo voy a hacer por partes en otro momento, pero por ahora está así y supongo que se puede apreciar así.

Lo que tiene el main es que se divide en ciertas partes, la primera es la cadena que se va a ingresar para ser procesada, la segunda es el procesamiento por partes de la cadena; y la tercera es como se realizan ciertas operaciones matemáticas para lograr el resultado final.
Las operaciones se hacen con los valores acumulados en un vector auxiliar.

Como ya les dije, no hagan pruebas con números literales de mas de 7 divisiones porque el programa no va a hacer nada al respecto.

Por ejemplo, esta cadena:
Código:
const char* cadenax = "ciento sesenta y dos mil trescientos treinta y seis\0";

el programa la reconoce como de 7 divisiones, pero no traten con cadenas de más divisiones porque no se maneja esa situación.

Código:

int main(){

// const char* cadenax = "ocho\0";
// const char* cadenax = "ocho mil seiscientos veintitres\0";
// const char* cadenax = "novecientos mil\0";
// const char* cadenax = "mil trescientos\0";
// const char* cadenax = "dos mil treinta y cinco\0";
// const char* cadenax = "cinco mil treinta y dos\0";
// const char* cadenax = "treinta y tres\0";
// const char* cadenax = "cinco mil\0";
// const char* cadenax = "veinte mil\0";
// const char* cadenax = "treinta y tres mil\0";
// const char* cadenax = "veintitres mil\0";
// const char* cadenax = "cuarenta y cinco mil quinientos\0";
// const char* cadenax = "veinticuatro mil quinientos\0";
// const char* cadenax = "veinticuatro mil quinientos veintiocho\0";
// const char* cadenax = "veinticuatro mil quinientos cuarenta y ocho\0";
// const char* cadenax = "veinticuatro mil quinientos ocho\0";
// const char* cadenax = "veinticuatro mil cien\0";
// const char* cadenax = "mil cuatrocientos cinco\0";
// const char* cadenax = "dos mil cinco\0";
// const char* cadenax = "dos mil cuarenta\0";
// const char* cadenax = "dos mil veintitres\0";
// const char* cadenax = "dos mil treinta y cinco\0";
// const char* cadenax = "cuarenta y cinco mil treinta y tres\0";
// const char* cadenax = "uno\0";
// const char* cadenax = "doscientos mil treinta y uno\0";
// const char* cadenax = "doscientos mil veintiuno\0";
// const char* cadenax = "doscientos mil uno\0";
// const char* cadenax = "ciento veinte mil\0";
// const char* cadenax = "ciento veinte mil dos\0";
// const char* cadenax = "ciento veinte mil trescientos seis\0";
// const char* cadenax = "ciento veinte mil trescientos veintisiete\0";
// const char* cadenax = "ciento veintiun mil dos\0";
// const char* cadenax = "ciento veinte mil trescientos treinta y seis\0";
// const char* cadenax = "ciento sesenta y un mil trescientos treinta y seis\0";
// const char* cadenax = "ciento sesenta y dos mil trescientos treinta y seis\0";
// const char* cadenax = "cero\0";
// const char* cadenax = "diez y nueve\0";
const char* cadenax = "diecinueve\0";

unsigned int len = strlen(cadenax);
unsigned int pos =0;
unsigned int vec_resultado[20]={0};
char str[256];
memset(str,0,sizeof(str));
for(unsigned int i=0; i<len;i++){

memset(str,0,sizeof(str));
if(cadenax[i] == ' '){

if(cadenax[i-1] == 'y') continue;

unsigned int x=1;
unsigned int j=i-1;
while(cadenax[j] != ' ' && j>0) {x++;j--;}
if(cadenax[j]==' ') {x--;j++;}
for(unsigned int l=0;l<x;l++){
str[l]=cadenax[j];
j++;
}
vec_resultado[pos++]= Equivalencia(str);
}

else if(i==(len-1)){

unsigned int x=1;
unsigned int j=i-1;
while(cadenax[j] != ' ' && j>0) {x++;j--;}
if(cadenax[j]==' ') {j++;}
else x++;
for(unsigned int l=0;l<x;l++){
str[l]=cadenax[j];
j++;
}
vec_resultado[pos++]= Equivalencia(str);
}
}

int resultado=0;
printf("Contenido del vector auxiliar: \n");
for(unsigned int k=0; (k<20&&vec_resultado[k]>0); k++) printf("%d\n",vec_resultado[k]);
int divisiones = DivisionesDeVector(vec_resultado,20);
// printf("divisiones: %d\n",divisiones);
// system("pause");

switch(divisiones){

case 1:{

resultado = vec_resultado[0];

  }break;
case 2:{

if(vec_resultado[1]>=1000)
resultado = vec_resultado[0]*vec_resultado[1];
else
resultado = vec_resultado[0]+vec_resultado[1];

  }break;
case 3:{

if(vec_resultado[0]>=1000){
resultado = vec_resultado[0]+vec_resultado[1];
resultado += vec_resultado[2];
} else
if(vec_resultado[1]>=1000){
resultado = vec_resultado[0]*vec_resultado[1];
resultado += vec_resultado[2];
} else
if(vec_resultado[2]>=1000){
resultado = vec_resultado[0]+vec_resultado[1];
resultado *= vec_resultado[2];
} else {
resultado = vec_resultado[0]*vec_resultado[1];
resultado += vec_resultado[2];
}

  }break;
case 4:{

if(vec_resultado[0]>=1000){

/* ????? */

} else
if(vec_resultado[1]>=1000){

resultado = vec_resultado[0]*vec_resultado[1];
resultado += vec_resultado[2];
resultado += vec_resultado[3];

} else
if(vec_resultado[2]>=1000){

resultado = vec_resultado[0]+vec_resultado[1];
resultado *= vec_resultado[2];
resultado += vec_resultado[3];

} else {

}

  }break;
case 5:{

if(vec_resultado[0]>=1000){

/* ????? */

} else
if(vec_resultado[1]>=1000){

resultado = vec_resultado[0]*vec_resultado[1];
resultado += vec_resultado[2];
resultado += vec_resultado[3]+vec_resultado[4];

} else
if(vec_resultado[2]>=1000){

resultado = vec_resultado[0]+vec_resultado[1];
resultado *= vec_resultado[2];
resultado += vec_resultado[3]+vec_resultado[4];

} else {

/* ????? */
}

  }break;
case 6:{

if(vec_resultado[0]>=1000){

/* ????? */

} else
if(vec_resultado[1]>=1000){

resultado = vec_resultado[0]*vec_resultado[1];
resultado += vec_resultado[2];
resultado += vec_resultado[3]+vec_resultado[4]+vec_resultado[5];

} else
if(vec_resultado[2]>=1000){

resultado = vec_resultado[0]+vec_resultado[1];
resultado *= vec_resultado[2];
resultado += vec_resultado[3]+vec_resultado[4]+vec_resultado[5];

} else {

/* ????? */
}

  }break;

case 7:{

if(vec_resultado[0]>=1000){

/* ????? */

} else
if(vec_resultado[1]>=1000){

resultado = vec_resultado[0]*vec_resultado[1];
resultado += vec_resultado[2];
resultado += vec_resultado[3]+vec_resultado[4]+vec_resultado[5]+vec_resultado[6];

} else
if(vec_resultado[2]>=1000){

resultado = vec_resultado[0]+vec_resultado[1];
resultado *= vec_resultado[2];
resultado += vec_resultado[3]+vec_resultado[4]+vec_resultado[5]+vec_resultado[6];

} else
if(vec_resultado[3]>=1000){

resultado = vec_resultado[0]+vec_resultado[1];
resultado += vec_resultado[2];
resultado *= vec_resultado[3];
resultado += vec_resultado[4]+vec_resultado[5]+vec_resultado[6];

} else {

/* ????? */
}

  }break;
}

printf("\n");
printf("resultado: %d\n",resultado);

while(getchar()!='\n');
return 0;
}