C. Listado de programas.

Anuncio
Anexo C. Listado de programas
C. Listado de programas.
C.1. Módulos de traducción.
C.1.1. Módulo para tildado con rasgos letras.
#include <string.h>
#include <stdio.h>
#include <values.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "silabica.h"
#include "tildes.h"
TEjemplo *ejemplos;
TIndiceEj ContEjemplos = 0; //Variable con el nº de ejemplos contados
TIndiceEj NumEjemplos = 0; //Variable con el nº de ejemplos que se van generando
char FicheroDicPalabras[MAXPATH]="drae_ej.dic";
char FicheroDicEjemplos[MAXPATH]="fich_ej.dic";
/*Esta funcion lee las palabras del diccionario*/
char *LeePalabraDiccionario(FILE *fichero)
{
char *linea=new char [1000];
char *punt;
char *palabra=NULL; //OJO:delete en donde se llame
if (fgets(linea,1000,fichero)!=NULL)
{
punt=strtok(linea, " ");
palabra=new char [strlen(punt)+1]; // +1: hace falta NULL para terminar
strcpy(palabra, punt);
for (int i=0; i<strlen(palabra); i++)
palabra[i]=Oem2Ansi(palabra[i]);
}
delete [] linea;
return palabra;
}
TIndicePal CalculaNumEjemplosPal(const char *pal)
{
return strlen(pal);
}
int EsVocal (char c)
{
switch (c)
{
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'á': case 'é': case 'í': case 'ó': case 'ú': case 'ü':
return 1;
default:
return 0;
}
}
int EstaTildada (char c)
{
switch (c)
{
case 'á': case 'é': case 'í': case 'ó': case 'ú':
return 1;
default:
return 0;
}
}
char elimina_tilde(char car)
{
switch (car)
{
case 'á':
car = 'a';
break;
case 'é':
car = 'e';
break;
case 'í':
car = 'i';
break;
case 'ó':
car = 'o';
break;
case 'ú':
C-1
Anexo C. Listado de programas
car = 'u';
break;
}
return car;
}
{
ventanas[contador][MAX_DESP]=(TValorRasgo) pal_desacent[i]; //Rasgo
central
for (j=1; j<=MAX_DESP; j++)
{
if (i-j<0)
ventanas[contador][MAX_DESP-j]=0;
else
ventanas[contador][MAX_DESP-j]=(TValorRasgo)
/*Esta función devuelve un array de soluciones para las vocales de la palabra dada*/
TValorSolucion *CalculaSoluciones(char *pal)
{
TIndicePal LongPal=CalculaNumEjemplosPal(pal);
TIndicePal i;
TIndicePal contador=0; //Lleva la cuenta de las soluciones (nº vocales)
int j;
TValorSolucion *soluciones=new TValorSolucion [LongPal+1];
for (i=0; i<LongPal; i++)
{
if (EsVocal(pal[i])==1)
{
if (EstaTildada(pal[i])==1)
soluciones[contador++]=ACENTUADA;
else
soluciones[contador++]=NO_ACENTUADA;
}
}
soluciones[contador]=FINALIZADOR;
return soluciones;
}
/*Esta función, dada una palabra, devuelve un array de ventanas de rasgos;
tantas como vocales tiene la palabra (este traductor es para el problema del
tildado, de ahí que sólo nos interesen ventanas cuyo rasgo central sea vocal)
Los rasgos que devuelve son los de las letras sin tildar*/
TVentana *DescomponeEnVentanas(char *pal)
{
TIndicePal LongPal=CalculaNumEjemplosPal(pal);
TVentana *ventanas=new TVentana[LongPal+1];
char *pal_desacent=new char[LongPal+1];
TIndicePal i;
TIndicePal contador=0; //Lleva la cuenta del nº de ventanas de la palabra=nº vocales
TIndiceRasgos j;
for (i=0; i<LongPal; i++)
{
pal_desacent[i]=elimina_tilde(pal[i]);
}
for (i=0; i<LongPal; i++)
{
if (EsVocal(pal[i])==1)
pal_desacent[i-j];
if (i+j>=LongPal)
ventanas[contador][MAX_DESP+j]=0;
else
ventanas[contador][MAX_DESP+j]=(TValorRasgo)
pal_desacent[i+j];
}
contador++;
}
}
ventanas[contador][0]=FINALIZADOR; //Finalizador de la cadena de ventanas
delete [] pal_desacent;
return ventanas;
}
/*Función que estima el número de ejemplos (es decir, para cada línea del
fichero diccionario de palabras, cuenta su nº de letras*/
TIndiceEj EstimaNumEjemplosFich(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; i<MAXINT && feof(fichero)==0; i++)
{
char *pal;
if (i%1000==0)
printf("Llevo contadas %ld palabras\n",(long)i);
if ((pal=LeePalabraDiccionario(fichero))!=NULL)
contador+=CalculaNumEjemplosPal(pal);
else
break;
delete [] pal;
}
if (i==MAXINT)
errorPrintf("Desbordamiento al leer %s%s",directorio,NomFichero);
C-2
Anexo C. Listado de programas
flhClose(fichero);
delete [] linea;
return contador;
}
/*Dado el fichero diccionario de palabras, carga en la variable ejemplos los
que va generando a partir de este fichero*/
TEjemplo *RellenaEjemplos(char *directorio,char *NomFichero)
{
int i;
int j;
TIndiceRasgos k;
char *palabra;
TVentana *ventanas;
TValorSolucion *SolucionesPalabra;
ejemplos=new TEjemplo [ContEjemplos];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0 && NumEjemplos<= ContEjemplos; i++)
{
if ((palabra=LeePalabraDiccionario(fichero))==NULL)
break;
if (i%1000==0)
printf("Cargando ejemplos en memoria. Llevo le'idas %ld
palabras\n",(long)i);
ventanas=DescomponeEnVentanas(palabra);
SolucionesPalabra=CalculaSoluciones(palabra);
for (j=0; ventanas[j][0]!=FINALIZADOR; j++)
{
for (k=0; k<NUM_RASGOS; k++)
{
ejemplos[NumEjemplos].rasgos[k]=ventanas[j][k];
}
ejemplos[NumEjemplos].solucion=SolucionesPalabra[j];
ejemplos[NumEjemplos].frecuencia=1; //Todavia no miro si hay ej
repetidos
strcpy(ejemplos[NumEjemplos].comentario,palabra);
NumEjemplos++;
}
delete [] palabra;
delete [] ventanas;
delete [] SolucionesPalabra;
}
flhClose(fichero);
return ejemplos;
}
/*Con esta funcion, escribimos en fichero los ejemplos (uno por cada linea).
La estructura es como sigue: nº de rasgos por ejemplo, 1er rasgo, 2º rasgo,...,
solucion, frecuencia, comentario\n*/
void EscribeFichero(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceRasgos j;
int k;
FILE *fichero=flhOpen(directorio,NomFichero,"wt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; i<NumEjemplos; i++)
{
k=fprintf(fichero,"%d ",(int)NUM_RASGOS);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero);
for (j=0; j<NUM_RASGOS; j++)
{
k=fprintf(fichero,"%.0f ", (float)ejemplos[i].rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero);
}
k=fprintf(fichero,"%.0f %.0f %s\n",
(float)ejemplos[i].solucion, (float)ejemplos[i].frecuencia,
ejemplos[i].comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero);
if (i%1000==0)
printf("Llevo escritos %ld ejemplos\n",(long)i);
}
flhClose(fichero);
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==3)
{
strcpy(FicheroDicPalabras,argv[1]);
strcpy(FicheroDicEjemplos,argv[2]);
}
C-3
Anexo C. Listado de programas
ContEjemplos=EstimaNumEjemplosFich(".\\", FicheroDicPalabras);
ejemplos=RellenaEjemplos(".\\", FicheroDicPalabras);
EscribeFichero(".\\", FicheroDicEjemplos);
delete [] ejemplos;
}
C.1.2. Módulo para tildado con rasgos letras más
rasgo de distancia silábica adicional.
/*Este traductor se diferencia del anterior en que la ventana de rasgos ahora tiene uno
más: aparte de los rasgos que utilizaba antes (ventana con un nº impar de letras),
tengo también el rasgo de distancia silábica a la última sílaba (nº de sílabas que
separan la sílaba donde se encuentra la letra (vocal) en estudio de la última síl.*/
#include <string.h>
#include <stdio.h>
#include <values.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "silabica.h"
#include "tildes2.h"
TEjemplo *ejemplos;
TIndiceEj ContEjemplos = 0; //Variable con el nº de ejemplos contados
TIndiceEj NumEjemplos = 0; //Variable con el nº de ejemplos que se van generando
char FicheroDicPalabras[MAXPATH]="drae_ej.dic";
char FicheroDicEjemplos[MAXPATH]="fich_ej2.dic";
/*Esta funcion lee las palabras del diccionario*/
char *LeePalabraDiccionario(FILE *fichero)
{
char *linea=new char [1000];
char *punt;
char *palabra=NULL; //OJO:delete en donde se llame
if (fgets(linea,1000,fichero)!=NULL)
{
punt=strtok(linea, " ");
palabra=new char [strlen(punt)+1]; // +1: hace falta NULL para terminar
strcpy(palabra, punt);
for (int i=0; i<strlen(palabra); i++)
palabra[i]=Oem2Ansi(palabra[i]);
}
delete [] linea;
return palabra;
}
TIndicePal CalculaNumEjemplosPal(const char *pal)
{
return strlen(pal);
}
int EsVocal (char c)
{
switch (c)
{
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'á': case 'é': case 'í': case 'ó': case 'ú': case 'ü':
return 1;
default:
return 0;
}
}
int EstaTildada (char c)
{
switch (c)
{
case 'á': case 'é': case 'í': case 'ó': case 'ú':
return 1;
default:
return 0;
}
}
char elimina_tilde(char car)
{
switch (car)
{
case 'á':
car = 'a';
break;
case 'é':
car = 'e';
break;
case 'í':
car = 'i';
break;
case 'ó':
car = 'o';
break;
C-4
Anexo C. Listado de programas
case 'ú':
car = 'u';
break;
}
return car;
}
/*Esta función devuelve el nº de sílabas que separan a la sílaba en la que se encuentra
la la "num_letra" letra de la palabra "pal", de la última sílaba. Si es la primera
letra, "num_letra" es 0*/
TValorRasgo CalculaDistUltimaSilaba (char *pal, int num_letra)
{
TIndicePal LongPal=CalculaNumEjemplosPal(pal);
int partir[MAX_NUM_SILABAS];
int i;
int NumSilabas=Silabica(pal,partir);
/*partir: array que devuelve la función Silabica. Su primer elemento es la
posición de la primera letra de la segunda sílaba (la de la 1ª siempre es 0)*/
if (num_letra<partir[0]||partir[0]==0)
return (TValorRasgo)(NumSilabas-1); //Si está en la primera sílaba o es monosílabo
//Para ver si está en la segunda sílaba o posteriores
for (i=0; partir[i]!=0; i++)
{
if (num_letra>=partir[i]&&(num_letra<partir[i+1]||partir[i+1]==0))
return (TValorRasgo)(NumSilabas-(i+2));
}
}
/*Esta función devuelve un array de soluciones para las vocales de la palabra dada*/
TValorSolucion *CalculaSoluciones(char *pal)
{
TIndicePal LongPal=CalculaNumEjemplosPal(pal);
TIndicePal i;
TIndicePal contador=0; //Lleva la cuenta de las soluciones (nº vocales)
int j;
TValorSolucion *soluciones=new TValorSolucion [LongPal+1];
for (i=0; i<LongPal; i++)
{
if (EsVocal(pal[i])==1)
{
if (EstaTildada(pal[i])==1)
soluciones[contador++]=ACENTUADA;
else
soluciones[contador++]=NO_ACENTUADA;
}
}
soluciones[contador]=FINALIZADOR;
return soluciones;
}
/*Esta función, dada una palabra, devuelve un array de ventanas de rasgos;
tantas como vocales tiene la palabra (este traductor es para el problema del
tildado, de ahí que sólo nos interesen ventanas cuyo rasgo central sea vocal)
Los rasgos que devuelve son los de las letras sin tildar*/
TVentana *DescomponeEnVentanas(char *pal)
{
TIndicePal LongPal=CalculaNumEjemplosPal(pal);
TVentana *ventanas=new TVentana[LongPal+2]; //1 más para el nuevo rasgo y otro para
el FINALIZADOR
memset(ventanas,0,(LongPal+2)*sizeof(TVentana));
char *pal_desacent=new char[LongPal+1];
TIndicePal i;
TIndicePal contador=0; //Lleva la cuenta del nº de ventanas de la palabra=nº vocales
TValorRasgo DistUltimaSilaba;
TIndiceRasgos j;
for (i=0; i<LongPal; i++)
{
pal_desacent[i]=elimina_tilde(pal[i]);
}
for (i=0; i<LongPal; i++)
{
if (EsVocal(pal[i])==1)
{
ventanas[contador][MAX_DESP]=(TValorRasgo) pal_desacent[i]; //Rasgo
central
for (j=1; j<=MAX_DESP; j++)
{
if (i-j<0)
ventanas[contador][MAX_DESP-j]=0;
else
ventanas[contador][MAX_DESP-j]=(TValorRasgo)
pal_desacent[i-j];
if (i+j>=LongPal)
ventanas[contador][MAX_DESP+j]=0;
else
ventanas[contador][MAX_DESP+j]=(TValorRasgo)
pal_desacent[i+j];
}
DistUltimaSilaba=CalculaDistUltimaSilaba(pal,i);
ventanas[contador][NUM_RASGOS]=DistUltimaSilaba;
contador++;
}
}
ventanas[contador][0]=FINALIZADOR; //Finalizador de la cadena de ventanas
delete [] pal_desacent;
return ventanas;
C-5
Anexo C. Listado de programas
}
/*Función que estima el número de ejemplos (es decir, para cada línea del
fichero diccionario de palabras, cuenta su nº de letras*/
TIndiceEj EstimaNumEjemplosFich(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; i<MAXINT && feof(fichero)==0; i++)
{
char *pal;
if (i%1000==0)
printf("Llevo contadas %ld palabras\n",(long)i);
if ((pal=LeePalabraDiccionario(fichero))!=NULL)
contador+=CalculaNumEjemplosPal(pal);
else
break;
delete [] pal;
}
if (i==MAXINT)
errorPrintf("Desbordamiento al leer %s%s",directorio,NomFichero);
flhClose(fichero);
delete [] linea;
return contador;
}
/*Dado el fichero diccionario de palabras, carga en la variable ejemplos los
que va generando a partir de este fichero*/
TEjemplo *RellenaEjemplos(char *directorio,char *NomFichero)
{
int i;
int j;
TIndiceRasgos k;
char *palabra;
TVentana *ventanas;
TValorSolucion *SolucionesPalabra;
ejemplos=new TEjemplo [ContEjemplos];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0 && NumEjemplos<= ContEjemplos; i++)
{
if ((palabra=LeePalabraDiccionario(fichero))==NULL)
break;
if (i%1000==0)
printf("Cargando ejemplos en memoria. Llevo le'idas %ld
palabras\n",(long)i);
ventanas=DescomponeEnVentanas(palabra);
SolucionesPalabra=CalculaSoluciones(palabra);
for (j=0; ventanas[j][0]!=FINALIZADOR; j++)
{
for (k=0; k<NUM_RASGOS+1; k++)
{
ejemplos[NumEjemplos].rasgos[k]=ventanas[j][k];
}
ejemplos[NumEjemplos].solucion=SolucionesPalabra[j];
ejemplos[NumEjemplos].frecuencia=1; //Todavia no miro si hay ej
repetidos
strcpy(ejemplos[NumEjemplos].comentario,palabra);
NumEjemplos++;
}
delete [] palabra;
delete [] ventanas;
delete [] SolucionesPalabra;
}
flhClose(fichero);
return ejemplos;
}
/*Con esta funcion, escribimos en fichero los ejemplos (uno por cada linea).
La estructura es como sigue: nº de rasgos por ejemplo, 1er rasgo, 2º rasgo,...,
solucion, frecuencia, comentario\n*/
void EscribeFichero(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceRasgos j;
int k;
FILE *fichero=flhOpen(directorio,NomFichero,"wt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; i<NumEjemplos; i++)
{
k=fprintf(fichero,"%d ",(int)(NUM_RASGOS+1)); //Tengo un rasgo adiciaonal
(dist. en sílabas a la última
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero);
C-6
Anexo C. Listado de programas
for (j=0; j<NUM_RASGOS+1; j++)
{
k=fprintf(fichero,"%.0f ", (float)ejemplos[i].rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero);
}
k=fprintf(fichero,"%.0f %.0f %s\n",
(float)ejemplos[i].solucion, (float)ejemplos[i].frecuencia,
ejemplos[i].comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero);
if (i%1000==0)
printf("Llevo escritos %ld ejemplos\n",(long)i);
}
flhClose(fichero);
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==3)
{
strcpy(FicheroDicPalabras,argv[1]);
strcpy(FicheroDicEjemplos,argv[2]);
}
ContEjemplos=EstimaNumEjemplosFich(".\\", FicheroDicPalabras);
ejemplos=RellenaEjemplos(".\\", FicheroDicPalabras);
EscribeFichero(".\\", FicheroDicEjemplos);
delete [] ejemplos;
}
C.1.3. Módulo para tildado con rasgos palabras.
#include <string.h>
#include <stdio.h>
#include <values.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "silabica.h"
#include "tildes.h"
TEjemplo *ejemplos;
TIndiceEj ContEjemplos = 0; //Variable con el nº de ejemplos contados
TIndiceEj NumEjemplos = 0; //Variable con el nº de ejemplos que se van generando
TIndiceEj NumRasgos = 0; /*Variable con el nº de rasgos que se van generando (nº de palabars
distintas que se va encontrando en el fichero de ambiguedades*/
TComentario *rasgos; /*Variable con todas las palabras
y signo de puntuación que va recogiendo de los ficheros de ambiguedades, para poder asociar
luego a cada palabra un rasgo (un número) y generar el correspondiente fichero*/
TIndiceEj ContPalEnEstudio_acen=0; //Contador con el número de pal. en estudio tildadas
TIndiceEj ContPalEnEstudio_desacen=0; //Contador con el número de pal. en estudio no tildadas
char FicheroDicPalabras[MAXPATH]="interrogativas.rpt";
char FicheroDicEjemplos[MAXPATH]="fich_ej.dic";
char FicheroDicRasgos[MAXPATH]="fich_rasgos.dic";
char FicheroProbabilidades[MAXPATH]="prob_entren.dic";
char pal_ant[MAXPATH]="";
char pal_sig[MAXPATH]="";
/*Esta función devuelve la palabra en estudio, la anterior y la siguiente del fichero
de ambiguedades*/
void LeePalabrasFichAmbiguas(FILE *fichero,TComentario *palabras)
{
char *linea=new char [1000];
char *punt;
int i;
memset(palabras,0,NUM_RASGOS*sizeof(TComentario));
if (fgets(linea,1000,fichero)!=NULL)
{
punt=strtok(linea, "\t\t");
punt+=strlen(punt)+2;
punt=strtok(punt, " ");
for (i=0; i<3; i++)
{
strcpy(palabras[i], punt);
punt=strtok(NULL, " ");
}
}
delete [] linea;
}
int EstaTildada (char c)
{
switch (c)
{
case 'á': case 'é': case 'í': case 'ó': case 'ú':
return 1;
default:
C-7
Anexo C. Listado de programas
pal_aux[i]=elimina_tilde(pal_aux[i]);
}
return 0;
}
}
char elimina_tilde(char car)
{
switch (car)
{
case 'á':
car = 'a';
break;
case 'é':
car = 'e';
break;
case 'í':
car = 'i';
break;
case 'ó':
car = 'o';
break;
case 'ú':
car = 'u';
break;
}
return car;
}
/*Esta función devuelve la solución para una palabra dada (tipo de categoría)*/
TValorSolucion CalculaSolucion(char *pal)
{
int LongPal=strlen(pal);
for (int i=0; i<LongPal; i++)
{
if (EstaTildada(pal[i])==1)
return ES_INTERROG;
}
return NO_ES_INTERROG;
}
/*Esta función pone todo en minúsculas la palabra pasada, además de destildarla*/
void PonEnMins(const char*pal,char *pal_aux)
{
int LongPal=strlen(pal);
strcpy(pal_aux,pal);
for (int i=0; i<LongPal; i++)
{
pal_aux[i]=AnsiTolower(pal[i]);
}
void EscribeFichRasgos(char *directorio,char *NomFichero,TComentario *rasgos,TIndiceEj contador)
{
TIndiceEj i;
int j;
FILE *fichero=flhOpen(directorio,NomFichero,"wt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; i<contador; i++)
{
if (i%100==0)
printf("Llevo escritos %ld rasgos\n",(long)i);
j=fprintf(fichero,"%s %ld\n",rasgos[i],(long)i);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero);
}
flhClose(fichero);
}
/*Esta función carga en memoria (y posteriormente en fichero) los rasgos del fichero
de ambiguedades: por cada palabra leída, le corresponde un rasgo (un número).
Cada línea contiene la palabra leída del diccionario de palabras y un número
(del 0 en adelante): su rasgo*/
TComentario *GeneraFichRasgos(char *directorio, char *NomFichero1, char *NomFichero2)
{
TComentario *palabras=new TComentario [NUM_RASGOS];
char *pal_aux=new char [40];
TIndiceEj i,k;
TIndiceRasgos j;
rasgos=new TComentario[ContEjemplos*NUM_RASGOS];
bool existeRasgo=false;
char *linea=new char [1000];
char *punt;
FILE *fichero1=flhOpen(directorio,NomFichero1,"rt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",NomFichero1);
}
for (i=0; feof(fichero1)==0; i++)
{
LeePalabrasFichAmbiguas(fichero1,palabras);
for (j=0; j<NUM_RASGOS; j++)
{
C-8
Anexo C. Listado de programas
PonEnMins(palabras[j],pal_aux);
for (k=0; k<NumRasgos; k++)
{
if (strcmp(pal_aux,rasgos[k])==0)
{
existeRasgo=true;
break;
}
}
if (existeRasgo==false)
{
if (NumRasgos%1000==0)
printf("Llevo cargados en memoria %ld
rasgos\n",(long)NumRasgos);
strcpy(rasgos[NumRasgos],pal_aux);
NumRasgos++;
}
else
existeRasgo=false;
}
}
EscribeFichRasgos(DIRECTORIO,NomFichero2,rasgos,NumRasgos);
flhClose(fichero1);
delete [] linea;
delete [] pal_aux;
delete [] palabras;
return rasgos;
}
/*Función que calcula el número de ejemplos para el fichero de ambiguedades dado
(calcula el número de líneas)*/
TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (i%100==0)
printf("Llevo contados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
/*Esta función devuelve la ventana de rasgos (palabras) a partir del array de palabras del
contexto (pal. central, pal. ant. y pal. sig.) y según el fichero diccionario de
palabras-rasgos*/
TValorRasgo *CalculaVentanaRasgos(char *directorio, TComentario *palabras)
{
TValorRasgo *ventana=new TValorRasgo [NUM_RASGOS];
memset(ventana,0,NUM_RASGOS*sizeof(TValorRasgo));
char *pal_aux=new char [40];
TIndiceRasgos i;
TIndiceEj j;
for (i=0; i<NUM_RASGOS; i++)
{
ventana[i]=-1;
for (j=0; j<NumRasgos; j++)
{
PonEnMins(palabras[i],pal_aux);
if (strcmp(rasgos[j],pal_aux)==0)
{
ventana[i]=j;
break;
}
}
if (ventana[i]==-1)
errorPrintf("Error en el fichero diccionario de palabras-rasgos");
}
delete [] pal_aux;
return ventana;
}
/*Para estudiar sólo un tipo de interrogativas por separado, ponemos un filtro*/
int EsPalabraEnEstudio(char *pal)
{
if (strcmp("*",PALABRA_EN_ESTUDIO)==0)
return 0;
else
{
if (strcmp(pal,PALABRA_EN_ESTUDIO)==0)
return 0;
else
return -1;
C-9
Anexo C. Listado de programas
}
}
/*Dado el fichero diccionario de palabras, carga en la variable ejemplos los
que va generando a partir de este fichero*/
TEjemplo *RellenaEjemplos(char *directorio,char *NomFichero)
{
int i;
int j;
TIndiceRasgos k;
TValorSolucion SolucionPalabra;
TValorRasgo *ventana;
ejemplos=new TEjemplo [ContEjemplos*NUM_RASGOS];
TComentario *palabras=new TComentario [NUM_RASGOS];
char *pal_en_estudio=new char [40];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0 && NumEjemplos<= ContEjemplos; i++)
{
LeePalabrasFichAmbiguas(fichero,palabras);
if (palabras[0][0]==0)
errorPrintf("Error de formato en el fichero %s",NomFichero);
if (i%100==0)
printf("Cargando ejemplos en memoria. Llevo le'idas %ld
palabras\n",(long)i);
PonEnMins(palabras[MAX_DESP],pal_en_estudio); //Palabra central (la paso a minúsculas y sin
tildes)
if (EsPalabraEnEstudio(pal_en_estudio)==0)
{
SolucionPalabra=CalculaSolucion(palabras[MAX_DESP]);
if (SolucionPalabra==ES_INTERROG)
ContPalEnEstudio_acen++;
else
ContPalEnEstudio_desacen++;
ventana=CalculaVentanaRasgos(directorio,palabras);
for (j=0; j<NUM_RASGOS; j++)
{
ejemplos[NumEjemplos].rasgos[j]=ventana[j];
}
ejemplos[NumEjemplos].solucion=SolucionPalabra;
ejemplos[NumEjemplos].frecuencia=1; //Todavia no miro si hay ej
repetidos
strcpy(ejemplos[NumEjemplos].comentario,palabras[MAX_DESP]);
NumEjemplos++;
delete [] ventana;
}
}
flhClose(fichero);
delete [] palabras;
delete [] pal_en_estudio;
return ejemplos;
}
/*Con esta funcion, escribimos en fichero los ejemplos (uno por cada linea).
La estructura es como sigue: nº de rasgos por ejemplo, 1er rasgo, 2º rasgo,...,
solucion, frecuencia, comentario\n
También escribimos un fichero de probabilidades, que nos dice el número de
palabras en estudio acentuadas y desacentuadas*/
void EscribeFicheros(char *directorio, char *NomFichero1, char *NomFichero2)
{
TIndiceEj i;
TIndiceRasgos j;
int k;
FILE *fichero1=flhOpen(directorio,NomFichero1,"wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",NomFichero1);
}
FILE *fichero2=flhOpen(directorio,NomFichero2,"wt");
if (fichero2==NULL)
{
errorPrintf("falta el fichero %s",NomFichero2);
}
for (i=0; i<NumEjemplos; i++)
{
k=fprintf(fichero1,"%d ",(int)NUM_RASGOS);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero1);
for (j=0; j<NUM_RASGOS; j++)
{
k=fprintf(fichero1,"%.0f ", (float)ejemplos[i].rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero1);
}
k=fprintf(fichero1,"%.0f %.0f %s\n",
(float)ejemplos[i].solucion, (float)ejemplos[i].frecuencia,
ejemplos[i].comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero1);
if (i%1000==0)
printf("Llevo escritos %ld ejemplos\n",(long)i);
}
C-10
Anexo C. Listado de programas
k=fprintf(fichero2,"%ld #Nº de palabras '%s' ACENTUADAS en el fich. de
entrenamiento\n",
(long)ContPalEnEstudio_acen, PALABRA_EN_ESTUDIO);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero2);
k=fprintf(fichero2,"%ld #Nº de palabras '%s' DESACENTUADAS el el fich. de
entrenamiento\n",
(long)ContPalEnEstudio_desacen, PALABRA_EN_ESTUDIO);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero2);
flhClose(fichero1);
flhClose(fichero2);
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==3)
{
strcpy(FicheroDicPalabras,argv[1]);
strcpy(FicheroDicEjemplos,argv[2]);
}
ContEjemplos=CalculaNumEjemplos(DIRECTORIO, FicheroDicPalabras);
rasgos=GeneraFichRasgos(DIRECTORIO, FicheroDicPalabras, FicheroDicRasgos);
ejemplos=RellenaEjemplos(DIRECTORIO, FicheroDicPalabras);
EscribeFicheros(DIRECTORIO, FicheroDicEjemplos, FicheroProbabilidades);
delete [] rasgos;
delete [] ejemplos;
}
C.1.4. Módulo para tareas de categorización.
#include <string.h>
#include <stdio.h>
#include <values.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "silabica.h"
#include "tildes.h"
TEjemplo *ejemplos;
//TIndiceEj ContEjemplos = 0; //Variable con el nº de ejemplos contados
TIndiceEj ContPalabrasCateg = 0; //Variable con el nº de palabras de los ficheros de cat.
TIndiceEj NumEjemplos = 0; //Variable con el nº de ejemplos que se van generando
TIndiceEj NumPalabrasCateg = 0; /*Variable con el nº de palabras distintas que se van
encontrando en los dicc. de categ.*/
TPalabraCateg *rasgos; /*Variable con todas las palabras que va recogiendo de los
ficheros de categorías, para poder asociar a cada palabra una semi-ventana de rasgos
y generar el correspondiente fichero*/
char FicheroDicPalabras[MAXPATH]="eval.aps";
char FicheroDicEjemplos[MAXPATH]="fich_ej.dic";
char FicheroDicRasgos[MAXPATH]="fich_rasgos.dic";
char FicheroProbabilidades[MAXPATH]="prob_entren.dic";
char FicherosDicCategorias[NUM_FICH_CATEG][MAX_PATH]={"corpus1.aps","corpus2.aps",
"corpus3.aps","corpus4.aps","corpus5.aps","corpus6.aps","corpus7.aps"};
char pal_ant[MAXPATH]="";
char pal_sig[MAXPATH]="";
/*Esta función devuelve la palabra leida del fich. de categ., junto con su categ.*/
TCategoria LeePalabraFichCateg(FILE *fichero, char *pal, int num_fichero)
{
char linea[1000];
char cat[40];
char *punt;
int i;
if (fgets(linea,1000,fichero)!=NULL)
{
punt=strtok(linea, " ");
if (punt==NULL)
errorPrintf("Error de formato en el diccionario de categ. nº
%d\n",num_fichero);
strcpy(pal,punt);
punt=NULL;
punt=strtok(punt, "\n");
if (punt==NULL)
errorPrintf("Error de formato en el diccionario de categ. nº
%d\n",num_fichero);
strcpy(cat,punt);
}
switch (cat[0])
{
case 'V':
return VERBO;
case 'N':
return NOMBRE;
case 'A':
return ADJETIVO;
case 'B':
return ADVERBIO;
C-11
Anexo C. Listado de programas
case 'R':
return PRONOMBRE;
case 'P':
return PREPOSICION;
case 'D':
return ARTICULO;
case 'C':
return CONJUNCION;
case 'I':
return INTERJECCION;
case 'M':
return MISCELANEA;
default:
return DESCONOCIDO;
}
}
int EstaTildada (char c)
{
switch (c)
{
case 'á': case 'é': case 'í': case 'ó': case 'ú':
return 1;
default:
return 0;
}
}
char elimina_tilde(char car)
{
switch (car)
{
case 'á':
car = 'a';
break;
case 'é':
car = 'e';
break;
case 'í':
car = 'i';
break;
case 'ó':
car = 'o';
break;
case 'ú':
car = 'u';
break;
}
return car;
}
/*Esta función devuelve la solución para una palabra dada (tipo de categoría)*/
TValorSolucion CalculaSolucion(TCategoria cat)
{
if (cat==VERBO)
return ES_VERBO;
else
return ES_NOMBRE;
}
/*Esta función pone todo en minúsculas la palabra pasada*/
void PonEnMins(const char*pal,char *pal_aux)
{
int LongPal=strlen(pal);
strcpy(pal_aux,pal);
for (int i=0; i<LongPal; i++)
{
pal_aux[i]=AnsiTolower(pal[i]);
}
}
/*Esta función destilda pal y lo devuelve en pal_aux*/
/*void EliminaTildePalabra(const char*pal,char *pal_aux)
{
int LongPal=strlen(pal);
strcpy(pal_aux,pal);
for (int i=0; i<LongPal; i++)
{
pal_aux[i]=elimina_tilde(pal_aux[i]);
}
} */
void EscribeFichRasgos(char *directorio,char *NomFichero,TIndiceEj contador)
{
TIndiceEj i;
int j;
FILE *fichero=flhOpen(directorio,NomFichero,"wt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
j=fprintf(fichero,"%s",rasgos[0].palabra);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero);
j=fprintf(fichero," %d",(int)rasgos[0].cat);
if (j==EOF)
C-12
Anexo C. Listado de programas
errorPrintf("Error en la escritura del fichero %s",NomFichero);
for (i=1; i<contador; i++)
{
if (i%1000==0)
printf("Llevo escritos %ld rasgos\n",(long)i);
j=fprintf(fichero,"\n%s",rasgos[i].palabra);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero);
j=fprintf(fichero," %d",(int)rasgos[i].cat);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero);
}
flhClose(fichero);
}
/*Esta función carga en memoria (y posteriormente en fichero) los rasgos de los ficheros
de categorias: por cada palabra leída, le corresponden 10 rasgos binarios(poniendo
a 0 o a 1 cada una de las 10 categorías básicas, según como aparece en tildes.h).
Cada línea contiene la palabra leída del diccionario de palabras y 10 números binarios*/
TPalabraCateg *GeneraFichRasgos(char *directorio, char ficheros[NUM_FICH_CATEG][MAX_PATH])
{
char *palabra=new char [40];
TCategoria categoria;
char *pal_aux=new char [40];
int i;
TIndiceEj j;
TIndiceRasgos l;
rasgos=new TPalabraCateg[ContPalabrasCateg+NUM_FICH_CATEG];//Reservo más por
las
//posibles líneas en blanco del final de los fich. de cat.
for (i=0; i<NUM_FICH_CATEG; i++)
{
FILE *fichero=flhOpen(directorio,ficheros[i],"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",ficheros[i]);
}
printf("Cargando las categor'ias del fichero nº %d...\n",i);
for (j=0; feof(fichero)==0; j++)
{
categoria=LeePalabraFichCateg(fichero,palabra,i);
PonEnMins(palabra,pal_aux);
if (NumPalabrasCateg%1000==0)
printf("Llevo cargadas en memoria %ld palabrascategor'ia\n",(long)NumPalabrasCateg);
strcpy(rasgos[NumPalabrasCateg].palabra,pal_aux);
rasgos[NumPalabrasCateg].cat=categoria;
NumPalabrasCateg++;
}
flhClose(fichero);
}
delete [] pal_aux;
delete [] palabra;
return rasgos;
}
/*Función que calcula el número de ejemplos para el fichero de ambiguedades dado
(calcula el número de líneas)*/
TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=1;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (i%1000==0)
printf("Llevo contados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
/*Función que calcula el número de palabras en los diccionarios de categorías
(calcula el número de líneas)*/
TIndiceEj CalculaNumPalabrasCateg(char *directorio, char
ficheros[NUM_FICH_CATEG][MAX_PATH])
{
TIndiceEj j;
TIndiceEj contador=1;
char *linea=new char [1000];
for (int i=0; i<NUM_FICH_CATEG; i++)
{
FILE *fichero=flhOpen(directorio,ficheros[i],"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",ficheros[i]);
C-13
Anexo C. Listado de programas
}
for (j=0; feof(fichero)==0; j++)
{
if (j%1000==0)
printf("Llevo contadas %ld palabras en el fichero de categ. nº
%d\n",(long)j,i);
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
}
delete [] linea;
return contador;
}
/*Esta función devuelve la ventana de rasgos (palabras) a partir de la del índice
por el que se encuentra recorriendo a la variable "rasgos" la función
"RellenaEjemplos"*/
TValorRasgo *CalculaVentanaRasgos(TIndiceEj indice)
{
TValorRasgo *ventana=new TValorRasgo [NUM_RASGOS];
memset(ventana,0,NUM_RASGOS*sizeof(TValorRasgo));
TIndiceRasgos i;
for (i=0; i<MAX_DESP; i++) //Palabra anterior
{
if (rasgos[indice-1].cat==(TCategoria)i)
ventana[i]=CATEGORIA_SI;
else
ventana[i]=CATEGORIA_NO;
}
que va generando a partir de este fichero*/
TEjemplo *RellenaEjemplos()
{
TIndiceEj i;
int j;
TValorSolucion SolucionPalabra;
TValorRasgo *ventana;
ejemplos=new TEjemplo [ContPalabrasCateg];
for (i=1; i<NumPalabrasCateg; i++) /*Empezamos en 1 pq la 1ª pal. no la consideramos
(no tenemos la anterior, para generar el ej.*/
{
if (rasgos[i].cat==VERBO||rasgos[i].cat==NOMBRE) //Para resolver sólo un tipo de amb.
{
if (NumEjemplos%1000==0)
printf("Cargando ejemplos en memoria. Llevo le'idas %ld
palabras-categor'ias\n",(long)NumEjemplos);
SolucionPalabra=CalculaSolucion(rasgos[i].cat);
ventana=CalculaVentanaRasgos(i);
for (j=0; j<NUM_RASGOS; j++)
{
ejemplos[NumEjemplos].rasgos[j]=ventana[j];
}
ejemplos[NumEjemplos].solucion=SolucionPalabra;
ejemplos[NumEjemplos].frecuencia=1; //Todavia no miro si hay ej
repetidos
strcpy(ejemplos[NumEjemplos].comentario,rasgos[i].palabra);//Palabra en estudio
NumEjemplos++;
delete [] ventana;
}
}
return ejemplos;
}
ventana[MAX_DESP]=CATEGORIA_NO; //Rasgo siempre a 0 para la pal. central
for (i=0; i<MAX_DESP; i++) //Palabra siguiente
{
if (rasgos[indice+1].cat==(TCategoria)i)
ventana[i+MAX_DESP+1]=CATEGORIA_SI;
else
ventana[i+MAX_DESP+1]=CATEGORIA_NO;
}
return ventana;
}
/*Dado el fichero diccionario de palabras, carga en la variable ejemplos los
/*Con esta funcion, escribimos en fichero los ejemplos (uno por cada linea).
La estructura es como sigue: nº de rasgos por ejemplo, 1er rasgo, 2º rasgo,...,
solucion, frecuencia, comentario\n*/
void EscribeFichero(char *directorio, char *NomFichero1)
{
TIndiceEj i;
TIndiceRasgos j;
int k;
FILE *fichero1=flhOpen(directorio,NomFichero1,"wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",NomFichero1);
}
C-14
Anexo C. Listado de programas
for (i=0; i<NumEjemplos; i++)
{
k=fprintf(fichero1,"%d ",(int)NUM_RASGOS);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero1);
for (j=0; j<NUM_RASGOS; j++)
{
k=fprintf(fichero1,"%.0f ", (float)ejemplos[i].rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero1);
}
k=fprintf(fichero1,"%.0f %.0f %s\n",
(float)ejemplos[i].solucion, (float)ejemplos[i].frecuencia,
ejemplos[i].comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero1);
if (i%1000==0)
printf("Llevo escritos %ld ejemplos\n",(long)i);
}
flhClose(fichero1);
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==3)
{
strcpy(FicheroDicPalabras,argv[1]);
strcpy(FicheroDicEjemplos,argv[2]);
}
//
ContEjemplos=CalculaNumEjemplos(DIRECTORIO, FicheroDicPalabras);
ContPalabrasCateg=CalculaNumPalabrasCateg("..\\..\\dicc_cat\\", FicherosDicCategorias);
rasgos=GeneraFichRasgos("..\\..\\dicc_cat\\", FicherosDicCategorias);
EscribeFichRasgos(DIRECTORIO,FicheroDicRasgos,NumPalabrasCateg);
ejemplos=RellenaEjemplos();
EscribeFichero(DIRECTORIO, FicheroDicEjemplos);
delete [] rasgos;
delete [] ejemplos;
}
C.1.5. Módulo para tareas de categorización con un
entrenamiento de palabras no ambiguas.
#include <string.h>
#include <stdio.h>
#include <values.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "silabica.h"
#include "tildes.h"
TEjemplo *ejemplos;
//TIndiceEj ContEjemplos = 0; //Variable con el nº de ejemplos contados
TIndiceEj ContPalabrasCateg = 0; //Variable con el nº de palabras de los ficheros de cat.
TIndiceEj NumEjemplos = 0; //Variable con el nº de ejemplos que se van generando
TIndiceEj NumEjemplosPrue = 0; /*Variable con el nº de ejemplos de evaluación (con
ambiguedad v_n) que se van generando*/
TIndiceEj NumPalabrasCateg = 0; /*Variable con el nº de palabras distintas que se van
encontrando en los dicc. de categ.*/
TPalabraCateg *rasgos; /*Variable con todas las palabras que va recogiendo de los
ficheros de categorías, para poder asociar a cada palabra una semi-ventana de rasgos
y generar el correspondiente fichero*/
TPalabraCategAmbig *rasgos_V_N; /*Variable con todas las palabras que va recogiendo de los
ficheros de categorías y que son o verbos o nombres, para poder distinguir luego
si una palabra tiene ambiguedad verbo-nombre o no. Las palabras se van almacenando
en minúsculas y sin tilde, para luego una más fácil comparación*/
TIndiceEj ContPalAmbiguas_V_N = 0; /*Variable con el nº de palabras con categoría
V o N que se van registrando al ir escribiendo los rasgos (y que pueden ser ambiguas
o no*/
char FicheroDicPalabras[MAXPATH]="eval.aps";
char FicheroDicEjemplosEntren[MAXPATH]="fich_ej.dic";
char FicheroDicEjemplosEval[MAXPATH]="fich_ej_prue.dic";
char FicheroDicRasgos[MAXPATH]="fich_rasgos.dic";
char FicheroDicRasgos_V_N[MAXPATH]="fich_rasgos_prue.dic";
char FicheroProbabilidades[MAXPATH]="prob_entren.dic";
char FicherosDicCategorias[NUM_FICH_CATEG][MAX_PATH]={"corpus1.aps","corpus2.aps",
"corpus3.aps","corpus4.aps","corpus5.aps","corpus6.aps","corpus7.aps","eval.aps"};
char pal_ant[MAXPATH]="";
char pal_sig[MAXPATH]="";
/*Esta función devuelve la palabra leida del fich. de categ., junto con su categ.*/
C-15
Anexo C. Listado de programas
switch (c)
TCategoria LeePalabraFichCateg(FILE *fichero, char *pal, int num_fichero)
{
char linea[1000];
char cat[40];
char *punt;
int i;
if (fgets(linea,1000,fichero)!=NULL)
{
punt=strtok(linea, " ");
if (punt==NULL)
errorPrintf("Error de formato en el diccionario de categ. nº
%d\n",num_fichero);
strcpy(pal,punt);
punt=NULL;
punt=strtok(punt, "\n");
if (punt==NULL)
errorPrintf("Error de formato en el diccionario de categ. nº
%d\n",num_fichero);
strcpy(cat,punt);
}
switch (cat[0])
{
case 'V':
return VERBO;
case 'N':
return NOMBRE;
case 'A':
return ADJETIVO;
case 'B':
return ADVERBIO;
case 'R':
return PRONOMBRE;
case 'P':
return PREPOSICION;
case 'D':
return ARTICULO;
case 'C':
return CONJUNCION;
case 'I':
return INTERJECCION;
case 'M':
return MISCELANEA;
default:
return DESCONOCIDO;
}
}
int EstaTildada (char c)
{
{
case 'á': case 'é': case 'í': case 'ó': case 'ú':
return 1;
default:
return 0;
}
}
char elimina_tilde(char car)
{
switch (car)
{
case 'á':
car = 'a';
break;
case 'é':
car = 'e';
break;
case 'í':
car = 'i';
break;
case 'ó':
car = 'o';
break;
case 'ú':
car = 'u';
break;
}
return car;
}
/*Esta función devuelve la solución para una palabra dada (tipo de categoría)*/
TValorSolucion CalculaSolucion(TCategoria cat)
{
if (cat==VERBO)
return ES_VERBO;
else
return ES_NOMBRE;
}
/*Esta función pone todo en minúsculas la palabra pasada*/
void PonEnMins(const char*pal,char *pal_aux)
{
int LongPal=strlen(pal);
strcpy(pal_aux,pal);
for (int i=0; i<LongPal; i++)
C-16
Anexo C. Listado de programas
{
pal_aux[i]=AnsiTolower(pal[i]);
}
}
/*Esta función destilda pal y lo devuelve en pal_aux*/
/*void EliminaTildePalabra(const char*pal,char *pal_aux)
{
int LongPal=strlen(pal);
strcpy(pal_aux,pal);
for (int i=0; i<LongPal; i++)
{
pal_aux[i]=elimina_tilde(pal_aux[i]);
}
} */
void EscribeFichRasgos(char *directorio,char *NomFichero1,char *NomFichero2,TIndiceEj
contador1,TIndiceEj contador2)
{
TIndiceEj i;
int j;
FILE *fichero1=flhOpen(directorio,NomFichero1,"wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",NomFichero1);
}
FILE *fichero2=flhOpen(directorio,NomFichero2,"wt");
if (fichero2==NULL)
{
errorPrintf("falta el fichero %s",NomFichero2);
}
j=fprintf(fichero1,"%s",rasgos[0].palabra);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero1);
j=fprintf(fichero1," %d",(int)rasgos[0].cat);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero1);
j=fprintf(fichero2,"%s",rasgos_V_N[0].palabra);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero2);
j=fprintf(fichero2," %d",(int)rasgos_V_N[0].cat);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero2);
for (i=1; i<contador1; i++)
{
if (i%1000==0)
printf("Llevo escritos %ld rasgos\n",(long)i);
j=fprintf(fichero1,"\n%s",rasgos[i].palabra);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero1);
j=fprintf(fichero1," %d",(int)rasgos[i].cat);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero1);
}
for (i=1; i<contador2; i++)
{
if (i%1000==0)
printf("Llevo escritos %ld rasgos ambiguos\n",(long)i);
j=fprintf(fichero2,"\n%s",rasgos_V_N[i].palabra);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero2);
j=fprintf(fichero2," %d",(int)rasgos_V_N[i].cat);
if (j==EOF)
errorPrintf("Error en la escritura del fichero %s",NomFichero2);
}
flhClose(fichero1);
flhClose(fichero2);
}
/*Esta función carga en memoria (y posteriormente en fichero) los rasgos de los ficheros
de categorias: por cada palabra leída le corresponde un nº con su categoría
(según como aparece en tildes.h). Cada línea contiene la palabra leída del diccionario
de palabras y 10 números binarios*/
TPalabraCateg *GeneraFichRasgos(char *directorio, char ficheros[NUM_FICH_CATEG][MAX_PATH])
{
char *palabra=new char [40];
TCategoria categoria;
char *pal_aux=new char [40];
int i;
TIndiceEj j,k;
int l,LongPal;
rasgos=new TPalabraCateg[ContPalabrasCateg+NUM_FICH_CATEG];//Reservo más por
las
//posibles líneas en blanco del final de los fich. de cat.
rasgos_V_N=new
TPalabraCategAmbig[ContPalabrasCateg+NUM_FICH_CATEG];//Reservo más por las
//posibles líneas en blanco del final de los fich. de cat.
bool existe_rasgo_V_N_nuevo=false;
for (i=0; i<NUM_FICH_CATEG; i++)
{
FILE *fichero=flhOpen(directorio,ficheros[i],"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",ficheros[i]);
}
printf("Cargando las categor'ias del fichero nº %d...\n",i);
for (j=0; feof(fichero)==0; j++)
{
C-17
Anexo C. Listado de programas
categoria=LeePalabraFichCateg(fichero,palabra,i);
PonEnMins(palabra,pal_aux);
if (NumPalabrasCateg%1000==0)
printf("Llevo cargadas en memoria %ld palabrascategor'ia\n",(long)NumPalabrasCateg);
strcpy(rasgos[NumPalabrasCateg].palabra,pal_aux);
rasgos[NumPalabrasCateg].cat=categoria;
if (categoria==VERBO||categoria==NOMBRE)
{
existe_rasgo_V_N_nuevo=true;
for (k=0; k<ContPalAmbiguas_V_N; k++)
{
LongPal=strlen(pal_aux);
for (l=0; l<LongPal; l++)
{
pal_aux[l]=elimina_tilde(pal_aux[l]);
}
if (strcmpi(pal_aux,rasgos_V_N[k].palabra)==0&&rasgos_V_N[k].ambig==false)
{
if ((rasgos_V_N[k].cat==VERBO&&categoria==NOMBRE)||
(rasgos_V_N[k].cat==NOMBRE&&categoria==VERBO))
{
rasgos_V_N[k].ambig=true;
existe_rasgo_V_N_nuevo=false;
break;
}
}
}
if (existe_rasgo_V_N_nuevo==true)
{
strcpy(rasgos_V_N[ContPalAmbiguas_V_N].palabra,pal_aux);
rasgos_V_N[ContPalAmbiguas_V_N].cat=categoria;
rasgos_V_N[ContPalAmbiguas_V_N].ambig=false;
existe_rasgo_V_N_nuevo=false;
ContPalAmbiguas_V_N++;
}
}
NumPalabrasCateg++;
}
flhClose(fichero);
}
delete [] pal_aux;
delete [] palabra;
return rasgos;
}
/*Función que calcula el número de ejemplos para el fichero de ambiguedades dado
(calcula el número de líneas)*/
TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=1;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (i%1000==0)
printf("Llevo contados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
/*Función que calcula el número de palabras en los diccionarios de categorías
(calcula el número de líneas)*/
TIndiceEj CalculaNumPalabrasCateg(char *directorio, char
ficheros[NUM_FICH_CATEG][MAX_PATH])
{
TIndiceEj j;
TIndiceEj contador=1;
char *linea=new char [1000];
for (int i=0; i<NUM_FICH_CATEG; i++)
{
FILE *fichero=flhOpen(directorio,ficheros[i],"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",ficheros[i]);
}
for (j=0; feof(fichero)==0; j++)
{
if (j%1000==0)
printf("Llevo contadas %ld palabras en el fichero de categ. nº
%d\n",(long)j,i);
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
C-18
Anexo C. Listado de programas
}
delete [] linea;
return contador;
}
/*Esta función devuelve la ventana de rasgos (palabras) a partir de la del índice
por el que se encuentra recorriendo a la variable "rasgos" la función
"RellenaEjemplos"*/
TValorRasgo *CalculaVentanaRasgos(TIndiceEj indice)
{
TValorRasgo *ventana=new TValorRasgo [NUM_RASGOS];
memset(ventana,0,NUM_RASGOS*sizeof(TValorRasgo));
TIndiceRasgos i;
for (i=0; i<MAX_DESP; i++) //Palabra anterior
{
if (rasgos[indice-1].cat==(TCategoria)i)
ventana[i]=CATEGORIA_SI;
else
ventana[i]=CATEGORIA_NO;
}
ventana[MAX_DESP]=CATEGORIA_NO; //Rasgo siempre a 0 para la pal. central
for (i=0; i<MAX_DESP; i++) //Palabra siguiente
{
if (rasgos[indice+1].cat==(TCategoria)i)
ventana[i+MAX_DESP+1]=CATEGORIA_SI;
else
ventana[i+MAX_DESP+1]=CATEGORIA_NO;
}
return ventana;
}
/*Con esta función vemos si una palabra tiene ambiguedad v_n, para separar los
ejemplos en distintos ficheros y así poder entrenar sólo con las no ambiguas
y evaluar las ambiguas*/
bool EsAmbiguaV_N(char *pal)
{
TIndiceEj i;
int j,LongPal;
char *pal_aux=new char [40];
for (i=0; i<ContPalAmbiguas_V_N; i++)
{
PonEnMins(pal,pal_aux);
LongPal=strlen(pal_aux);
for (j=0; j<LongPal; j++)
{
pal_aux[j]=elimina_tilde(pal_aux[j]);
}
if (strcmp(rasgos_V_N[i].palabra,pal_aux)==0&&rasgos_V_N[i].ambig==true)
{
delete [] pal_aux;
return true;
}
}
delete [] pal_aux;
return false;
}
/*Dado el fichero diccionario de palabras, carga en la variable ejemplos los
que va generando a partir de este fichero*/
TEjemplo *RellenaEjemplos()
{
TIndiceEj i;
int j;
TValorSolucion SolucionPalabra;
TValorRasgo *ventana;
ejemplos=new TEjemplo [ContPalabrasCateg];
for (i=1; i<NumPalabrasCateg; i++) /*Empezamos en 1 pq la 1ª pal. no la consideramos
(no tenemos la anterior, para generar el ej.*/
{
if (rasgos[i].cat==VERBO||rasgos[i].cat==NOMBRE) //Para resolver sólo un tipo de amb.
{
if (NumEjemplos%1000==0)
printf("Cargando ejemplos en memoria. Llevo le'idas %ld
palabras-categor'ias\n",(long)NumEjemplos);
SolucionPalabra=CalculaSolucion(rasgos[i].cat);
ventana=CalculaVentanaRasgos(i);
for (j=0; j<NUM_RASGOS; j++)
{
ejemplos[NumEjemplos].rasgos[j]=ventana[j];
}
ejemplos[NumEjemplos].solucion=SolucionPalabra;
ejemplos[NumEjemplos].frecuencia=1; //Todavia no miro si hay ej
repetidos
strcpy(ejemplos[NumEjemplos].comentario,rasgos[i].palabra);//Palabra en estudio
ejemplos[NumEjemplos].ambig=EsAmbiguaV_N(rasgos[i].palabra);
NumEjemplos++;
delete [] ventana;
}
}
return ejemplos;
C-19
Anexo C. Listado de programas
errorPrintf("error en la escritura del fichero
}
%s",NomFichero2);
/*Con esta funcion, escribimos en fichero los ejemplos (uno por cada linea).
La estructura es como sigue: nº de rasgos por ejemplo, 1er rasgo, 2º rasgo,...,
solucion, frecuencia, comentario\n*/
void EscribeFicheros(char *directorio, char *NomFichero1,char *NomFichero2)
{
TIndiceEj i;
TIndiceRasgos j;
int k;
FILE *fichero1=flhOpen(directorio,NomFichero1,"wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",NomFichero1);
}
FILE *fichero2=flhOpen(directorio,NomFichero2,"wt");
if (fichero2==NULL)
{
errorPrintf("falta el fichero %s",NomFichero2);
}
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].ambig==false)
{
k=fprintf(fichero1,"%d ",(int)NUM_RASGOS);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero1);
for (j=0; j<NUM_RASGOS; j++)
{
k=fprintf(fichero1,"%.0f ", (float)ejemplos[i].rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero1);
}
k=fprintf(fichero1,"%.0f %.0f %s\n",
(float)ejemplos[i].solucion, (float)ejemplos[i].frecuencia,
ejemplos[i].comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero1);
}
else
{
k=fprintf(fichero2,"%d ",(int)NUM_RASGOS);
if (k==EOF)
for (j=0; j<NUM_RASGOS; j++)
{
k=fprintf(fichero2,"%.0f ", (float)ejemplos[i].rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero2);
}
k=fprintf(fichero2,"%.0f %.0f %s\n",
(float)ejemplos[i].solucion, (float)ejemplos[i].frecuencia,
ejemplos[i].comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero2);
}
if (i%1000==0)
printf("Llevo escritos %ld ejemplos\n",(long)i);
}
flhClose(fichero1);
flhClose(fichero2);
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==3)
{
strcpy(FicheroDicEjemplosEntren,argv[1]);
strcpy(FicheroDicEjemplosEval,argv[2]);
}
//
ContEjemplos=CalculaNumEjemplos(DIRECTORIO, FicheroDicPalabras);
ContPalabrasCateg=CalculaNumPalabrasCateg("..\\..\\dicc_cat\\", FicherosDicCategorias);
rasgos=GeneraFichRasgos("..\\..\\dicc_cat\\", FicherosDicCategorias);
EscribeFichRasgos(DIRECTORIO,FicheroDicRasgos,FicheroDicRasgos_V_N,NumPalabrasCateg,Co
ntPalAmbiguas_V_N);
ejemplos=RellenaEjemplos();
EscribeFicheros(DIRECTORIO, FicheroDicEjemplosEntren, FicheroDicEjemplosEval);
delete [] rasgos;
delete [] rasgos_V_N;
delete [] ejemplos;
}
C-20
Anexo C. Listado de programas
C.2. Módulo de entrenamiento.
#include <string.h>
#include <stdio.h>
#include <values.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "silabica.h"
#include "tildes.h"
TEjemplo *ejemplos;
TIndiceEj NumEjemplos; //Numero de ejemplos una vez depurados
TIndiceRasgos NumRasgos;
char FicheroDicEjemplos[MAXPATH]="fich_ej.dic";
char FicheroBaseDatos[MAXPATH]="bd_ej.dic";
float LeeFlotante(char *token, int i)
{
float float_aux;
if(sscanf(token,"%f",(float*)&float_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return float_aux;
}
int LeeEntero(char *token)
{
int int_aux;
if(sscanf(token,"%d",(int*)&int_aux)!=1)
{
errorPrintf("error de formato\n");
}
return int_aux;
}
/*Esta funcion devuelve el siguiente ejemplo sin depurar del diccionario*/
TEjemplo LeeEjemplo(FILE *fichero, TIndiceEj i)
{
TEjemplo EjemploCandidato;
char *linea=new char [1000];
char *punt=linea;
if (fgets(linea,1000,fichero)!=NULL)
{
float aux_float;
punt=strtok(punt, " ");
if (punt==NULL)
{
errorPrintf("error de formato\n");
}
NumRasgos = LeeEntero(punt);
for (int j=0; j<NumRasgos; j++)
{
punt = NULL;
punt=strtok(punt, " ");
EjemploCandidato.rasgos[j]=LeeFlotante(punt,i);
}
punt=strtok(NULL, " ");
if (punt==NULL)
{
errorPrintf("error de formato\n");
}
EjemploCandidato.solucion=LeeEntero(punt);
punt=strtok(NULL, " ");
if (punt==NULL)
{
errorPrintf("error de formato\n");
}
EjemploCandidato.frecuencia=LeeFlotante(punt,i);
punt=strtok(NULL, "\n");
if (punt==NULL)
{
errorPrintf("error de formato\n");
}
strcpy(EjemploCandidato.comentario,punt);
}
delete [] linea;
return EjemploCandidato;
}
static TValorSolucion solucionAComparar;
int comparaEjemplos(const void *x, const void *y)
{
TValorRasgo *vent=(TValorRasgo *)x;
TEjemplo *ej=(TEjemplo *)y;
if (solucionAComparar!=ej->solucion)
return 1;
for (int i=0; i<NumRasgos; i++)
{
C-21
Anexo C. Listado de programas
}
if (vent[i]!=ej->rasgos[i])
return 1;
}
}
}
return NO_EXISTE;
return 0;
#endif
}
}
/*Esta funcion devuelve cero (NO_EXISTE) si no existe (y con la misma solucion)
como ejemplo el que se le pasa como par'ametro. Y si existe, se aumenta su frecuencia*/
TExistenciaEjemplo ExisteEjemplo(TEjemplo ejemplo)
{
TIndiceEj i;
#ifdef __WIN32__
TEjemplo EjAuxiliar;
if (ejemplo.rasgos[0]==FINALIZADOR)
{
return NO_EXISTE;
}
if (NumEjemplos==0)
{
return NO_EXISTE;
}
for (i=0; i<NumRasgos && ejemplo.rasgos[i]!=FINALIZADOR; i++)
{
EjAuxiliar.rasgos[i]=ejemplo.rasgos[i];
if (i<NumRasgos-1)
EjAuxiliar.rasgos[i+1]=FINALIZADOR;
}
solucionAComparar=ejemplo.solucion;
TEjemplo * ej=(TEjemplo * )lfind((const void*)&EjAuxiliar,(const void*)ejemplos,(unsigned
int*)&NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);
if (ej!=NULL)
{
ej->frecuencia++;
return EXISTE;
}
else
return NO_EXISTE;
#else
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion==ejemplo.solucion)
{
if (comparaEjemplos(ventana,&(ejemplos[i]))==0)
{
ejemplos[i].frecuencia++;
return EXISTE;
/*Funcion que estima el numero de ejemplos (es decir, nº de lineas del fichero
diccionario de ejemplos sin depurar*/
TIndiceEj EstimaNumEjemplosFich(char *directorio, char *NomFichero)
{
TIndiceEj i;
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
char *linea=new char [1000];
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; i<MAXINT && feof(fichero)==0; i++)
{
if (i%1000==0)
printf("Llevo contados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)==NULL)
break;
}
if (i==MAXINT)
errorPrintf("Desbordamiento al leer %s%s",directorio,NomFichero);
flhClose(fichero);
delete [] linea;
return i;
}
/*Dado el fichero diccionario de palabras, carga en la variable ejemplos los
que va generando a partir de este fichero*/
TEjemplo *RellenaEjemplos(char *directorio,char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0; //Nº de ejemplos que se llevan generados
TEjemplo ejemplo;
TIndiceEj ContEjemplos=EstimaNumEjemplosFich(directorio,NomFichero);
//Variable con el nº de ejemplos estimados
ejemplos=new TEjemplo [ContEjemplos];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
C-22
Anexo C. Listado de programas
}
for (i=0; feof(fichero)==0 && i<ContEjemplos; i++)
{
ejemplo = LeeEjemplo(fichero,i);
if (ExisteEjemplo(ejemplo) == NO_EXISTE)
{
ejemplos[contador] = ejemplo;
ejemplos[contador].frecuencia = (float) 1;
contador++;
NumEjemplos=contador;
}
//Si existiese el ejemplo, la frecuencia ya se habría incrementado en la función
ExisteEjemplo
if (i%1000==0)
printf("Llevo le'idos %ld ejemplos\n",(long)i);
}
flhClose(fichero);
return ejemplos;
}
/*Con esta funcion, escribimos en fichero los ejemplos (uno por cada linea).
La estructura es como sigue: nº de rasgos por ejemplo, 1 blanco, 1er rasgo,
1 blanco, 2º rasgo,..., 1 blanco, solucion, 1 blanco, frecuencia, blanco, coment.\n*/
void EscribeFichero(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceRasgos j;
int k;
FILE *fichero=flhOpen(directorio,NomFichero,"wt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; i<NumEjemplos; i++)
{
k=fprintf(fichero,"%d ",(int)NumRasgos);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero);
for (j=0; j<NumRasgos; j++)
{
k=fprintf(fichero,"%.0f ", (float)ejemplos[i].rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",NomFichero);
}
k=fprintf(fichero,"%d ", ejemplos[i].solucion);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero);
k=fprintf(fichero,"%.0f %s\n", (float)ejemplos[i].frecuencia,
ejemplos[i].comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",NomFichero);
if (i%100==0)
printf("Llevo escritos %ld ejemplos\n",(long)i);
}
flhClose(fichero);
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==3)
{
strcpy(FicheroDicEjemplos,argv[1]);
strcpy(FicheroBaseDatos,argv[2]);
}
ejemplos=RellenaEjemplos(".\\" , FicheroDicEjemplos);
EscribeFichero(".\\", FicheroBaseDatos);
delete [] ejemplos;
}
C.3. Módulo de pesos.
//Para llamarlo, se puede hacer con par'ametros por este orden: FBD, FPesos, FEstPesos
#include <assert.h>
#include "silabica.h"
#include <string.h>
#include <stdio.h>
#include <values.h>
#include <math.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "tildes.h"
TEjemplo *ejemplos;
TIndiceEj NumEjemplos;
TDistancia *pesos;
TIndiceRasgos NumRasgos = 0; //Nº de rasgos leídos del fichero BD
C-23
Anexo C. Listado de programas
char FicheroBaseDatos[MAXPATH]="bd_ej.dic";
char FicheroPesos[MAXPATH]="pesos.dic";
char FicheroEstadisPesos[MAXPATH]="pesos.est";
TValorRasgo MinValorRasgo=MAXINT;
TValorRasgo MaxValorRasgo=-MAXINT;
/*Funcion que calcula el numero de ejemplos (es decir, el numero de lineas del
fichero de ejemplos*/
TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
int comparaEjemplos(const void *x, const void *y)
{
TValorRasgo *vent=(TValorRasgo *)x;
TEjemplo *ej=(TEjemplo *)y;
for (int i=0; i<NumRasgos; i++)
{
if (vent[i]>ej->rasgos[i])
return 1;
else if (vent[i]<ej->rasgos[i])
return -1;
}
return 0;
}
float LeeFlotante(char *token, int i)
{
float float_aux;
if(sscanf(token,"%f",(float*)&float_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return float_aux;
}
int LeeSolucion(char *token, int i)
{
int int_aux;
if(sscanf(token,"%d",(int*)&int_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return int_aux;
}
/*Esta funcion carga en la variable ejemplos los datos del fichero diccionario
de ejemplos (que contiene en cada linea un ejemplo (una ventana de rasgos),
una solucion y la frecuencia de ese ejemplo). Cada linea del fichero de
entrada es como sigue: nº de rasgos por ejemplo, blanco, nº de 1er rasgo,
blanco,..., solucion, blanco, frecuencia, blanco, comentario*/
TEjemplo* CargaEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
char *linea=new char [1000];
NumEjemplos=CalculaNumEjemplos(directorio, NomFichero);
if (NumEjemplos<=0)
{
errorPrintf("fichero vac'io: %s",NomFichero);
return NULL;
}
ejemplos=new TEjemplo[NumEjemplos];
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (i%1000==0)
printf("Llevo cargados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
{
TIndiceRasgos j;
char *token=linea;
token=strtok(token," ");
NumRasgos = atoi(token);
C-24
Anexo C. Listado de programas
token = NULL;
for (j=0; j<NumRasgos; j++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
float aux=LeeFlotante(token,i);
if (aux<MinValorRasgo)
MinValorRasgo=aux;
if (aux>MaxValorRasgo)
MaxValorRasgo=aux;
ejemplos[i].rasgos[j] = aux;
token=NULL;
}
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].solucion = LeeSolucion(token,i);
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].frecuencia = LeeFlotante(token,i);
if (ejemplos[i].frecuencia<=0)
{
errorPrintf("error de formato en l'inea %ld",(long)i);
}
token=strtok(NULL,"\n");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
strcpy(ejemplos[i].comentario,token);
}
/*Esta funci'on genera el conjunto de ejemplos cuyo rasgo NumRasgo tiene valor
igual a ValorRasgo*/
TEjemplo *CreaConjuntoEj(TIndiceRasgos NumRasgo,TValorRasgo ValorRasgo)
{
TIndiceEj i;
TIndiceEj ContadorConjuntoEj = 0;
TEjemplo *ConjuntoEj=new TEjemplo[NumEjemplos];
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].rasgos[NumRasgo] == ValorRasgo)
{
ConjuntoEj[ContadorConjuntoEj++] = ejemplos[i];
}
}
ConjuntoEj[ContadorConjuntoEj].solucion = FINALIZADOR;
return ConjuntoEj;
}
/*Esta funci'on calcula la cardinalidad de un conjunto de ejemplos dado*/
TIndiceEj cardinal(TEjemplo *ConjuntoEj)
{
TIndiceEj i;
TIndiceEj ContadorConjuntoEj = 0;
for (i=0; ConjuntoEj[i].solucion != FINALIZADOR; i++)
{
ContadorConjuntoEj++;
}
return ContadorConjuntoEj;
}
float log2(float x)
{
return log10(x)/log10(2);
}
else
{
break;
}
}
flhClose(fichero);
delete [] linea;
qsort(ejemplos, NumEjemplos, sizeof(ejemplos[0]),comparaEjemplos);
return ejemplos;
}
float Entropia(float p)
{
if (p>0)
{
return -p*log2(p);
}
else
{
return 0;
}
C-25
Anexo C. Listado de programas
}
/*Estas funciones recorren la variable ejemplos, para dar las soluc. max y min*/
TIndiceEj CalculaMinSoluc()
{
TIndiceEj MinSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion < MinSoluc) MinSoluc = ejemplos[i].solucion;
}
return MinSoluc;
}
TIndiceEj CalculaMaxSoluc()
{
TIndiceEj MaxSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion > MaxSoluc) MaxSoluc = ejemplos[i].solucion;
}
return MaxSoluc;
}
/*Esta funci'on calcula la entrop'ia de la informaci'on de la Base de Datos
(diccionario de ejemplos), calculada como el sumatorio en i de los productos
de las probabilidades de la soluci'on i por el log2 de dichas prob.*/
TEntropia CalculaEntropiaInfoBD()
{
TIndiceEj i,j;
TEntropia entropia=0;
TIndiceEj maxSoluc=CalculaMaxSoluc();
TIndiceEj minSoluc=CalculaMinSoluc();
TIndiceEj rangoSoluc=maxSoluc-minSoluc+1;
TIndiceEj *FrecuenciaSolucion = new TIndiceEj[rangoSoluc];
printf("\n Calculando la entrop'ia de la informaci'on de la base de datos...\n");
for (i=minSoluc; i<=maxSoluc; i++)
{
FrecuenciaSolucion[i] = 0;
}
for (i=0; i<NumEjemplos; i++)
{
for (j=minSoluc; j<=maxSoluc; j++)
{
if (ejemplos[i].solucion == j) FrecuenciaSolucion[j]++;
}
}
for (j=minSoluc; j<=maxSoluc; j++)
{
entropia += Entropia((float)FrecuenciaSolucion[j]/(float)NumEjemplos);
}
return entropia;
}
/*Esta funci'on calcula la entrop'ia media de la informaci'on para un rasgo*/
TEntropia CalculaEntropiaRasgo(TIndiceRasgos NumRasgo)
{
TValorRasgo ValorRasgo;
TEntropia entropia = 0;
// = H(D(f))
TIndiceEj NumEjemplosValorRasgo;
TEntropia EntropiaValor=0;
// = H(D(f=vi))
TIndiceEj i,j;
printf("\n
Calculando la entrop'ia del rasgo nº %d\n",(int) NumRasgo);
for (ValorRasgo=MinValorRasgo; ValorRasgo<=MaxValorRasgo; ValorRasgo++)
{
TEjemplo *ConjuntoEj = CreaConjuntoEj(NumRasgo,ValorRasgo);
NumEjemplosValorRasgo = cardinal(ConjuntoEj);
TIndiceEj maxSoluc=CalculaMaxSoluc();
TIndiceEj minSoluc=CalculaMinSoluc();
TIndiceEj rangoSoluc=maxSoluc-minSoluc+1;
TIndiceEj *FrecuenciaSolucion = new TIndiceEj[rangoSoluc];
for (i=0; i<NumEjemplosValorRasgo; i++)
{
for (j=minSoluc; j<=maxSoluc; j++)
{
if (ConjuntoEj[i].solucion == j) FrecuenciaSolucion[j]++;
}
}
for (j=minSoluc; j<=maxSoluc; j++)
{
EntropiaValor +=
Entropia((float)FrecuenciaSolucion[j]/(float)NumEjemplos);
}
entropia +=
(EntropiaValor*(float)NumEjemplosValorRasgo/(float)NumEjemplos);
delete [] ConjuntoEj;
}
return entropia;
}
/*Esta funci'on carga en la variable global pesos los pesos de cada rasgo para
su posterior utilizaci'on en el c'alculo de la distancia entre ventanas de rasgos.
C-26
Anexo C. Listado de programas
Adem'as, genera un fichero con estad'sticas de los pesos, llamado "pesos.est"*/
void InicializaPesos()
{
int k;
TIndiceRasgos i;
printf("\n Calculando pesos...\n");
TEntropia EntropiaInfoBD = CalculaEntropiaInfoBD();
FILE *fichero = flhOpen(".\\",FicheroEstadisPesos,"wt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",FicheroEstadisPesos);
}
pesos = new TEntropia[NumRasgos];
printf("\n Calculando la entrop'ia de los distintos rasgos...\n");
for (i=0; i<NumRasgos; i++)
{
TEntropia EntropiaRasgo = CalculaEntropiaRasgo(i);
pesos[i] = (EntropiaInfoBD - EntropiaRasgo);
k = fprintf(fichero, "Peso rasgo nº %d : %f\n", i, pesos[i]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisPesos);
k = fprintf(fichero, "Entropia rasgo nº %d : %f\n", i, EntropiaRasgo);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisPesos);
}
k = fprintf(fichero, "Entropia Informacion de la BD: %f\n", EntropiaInfoBD);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",FicheroEstadisPesos);
flhClose(fichero);
}
{
k = fprintf(fichero, "%f ",pesos[i]);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",FicheroPesos);
}
k = fprintf(fichero, "\n");
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",FicheroPesos);
flhClose(fichero);
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==4)
{
strcpy(FicheroBaseDatos,argv[1]);
strcpy(FicheroPesos,argv[2]);
strcpy(FicheroEstadisPesos,argv[3]);
}
ejemplos=CargaEjemplos(".\\", FicheroBaseDatos);
if (ejemplos!=NULL)
{
InicializaPesos();
EscribeFicheroPesos();
}
delete [] ejemplos;
delete [] pesos;
}
C.4. Módulo de evaluación.
/*Esta funci'on escribe en fichero los pesos para su posterior utilizaci'on por el evaluador*/
void EscribeFicheroPesos()
{
int k;
TIndiceRasgos i;
FILE *fichero = flhOpen(".\\",FicheroPesos,"wt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",FicheroPesos);
}
k = fprintf(fichero, "%d ", NumRasgos);
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",FicheroPesos);
for (i=0; i<NumRasgos; i++)
#include <assert.h>
#include "silabica.h"
#include <string.h>
#include <stdio.h>
#include <values.h>
#include <math.h>
#include <mem.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "tildes2.h"
TEjemplo *ejemplos;
C-27
Anexo C. Listado de programas
{
if (distancia(ejemplos[i].rasgos,rasgos)<distMin)
{
distMin=distancia(ejemplos[i].rasgos,rasgos);
indMin=i;
}
}
assert(indMin>=0);
return indMin;
}
TIndiceEj NumEjemplos; //Nº de ejemplos de la BD de entrenamiento
TDistancia *pesos;
TIndiceRasgos NumRasgos = 0; //Variable con el n'umero de rasgos que lee desde el fichero BD de
ejemplos
TValorSolucion SolucionEvaluada;
TFrecuencia frecSolucMasProbable=0; //Guarda la frec. de la soluc + probable para cada vantana
evaluada
TDistancia distMin=0; //Guarda la dist. min. de cada ventana de rasgos a los ej de dist mínima
char FicheroPruebas[MAXPATH]="fich_prue_tildes2.dic"; //Fichero con todos las palabras para
evaluar (pasado por el traductor)
char FicheroBDEjemplos[MAXPATH]="bd_ej2.dic";//Fichero con ejemplos y soluciones
char FicheroPesos[MAXPATH]="pesos2.dic"; //Fichero con los pesos
char FicheroEvaluacion[MAXPATH]="evaluacion2.est"; //Fichero con todas las ventanas evaluadas.
/*El formato de evaluacion.est es: nºrasgos, 1er rasgo,...,último rasgo, solución según se
ha leído del texto de pruebas, solucion estimada por el evaluador, frecuencia acumulada
de lo/s ejemplo/s de dist. mínima cuya solución se ha tomado como la más probable,
distancia mínima a lo/s ejemplo/s de dist. mínima y comentario (palabra leída del texto
de pruebas, de la que se ha obtenido la ventana en estudio*/
char FicheroEstadisticasEvaluacion[MAXPATH]="estadis.est"; // Fichero con las estad'isticas
TDistancia DistanciaRasgos(TValorRasgo a, TValorRasgo b)
{
if (a==b)
return 0;
else
return 1;
}
TDistancia distancia(TValorRasgo *ejemp1, TValorRasgo *ejemp2)
{
TIndiceRasgos i;
TDistancia Distancia;
for (i=0,Distancia=0; i<NumRasgos; i++)
{
Distancia+=pesos[i]*DistanciaRasgos(ejemp1[i],ejemp2[i]);
}
return Distancia;
}
/*Esta funcion busca el primer ejemplo de distancia minima*/
TIndiceEj BuscaMinimo(TValorRasgo *rasgos)
{
TDistancia distMin=MAXINT;
TIndiceEj indMin=-MAXINT;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
int comparaEjemplos(const void *x, const void *y)
{
TValorRasgo *vent=(TValorRasgo *)x;
TEjemplo *ej=(TEjemplo *)y;
for (int i=0; i<NumRasgos; i++)
{
if (vent[i]>ej->rasgos[i])
return 1;
else if (vent[i]<ej->rasgos[i])
return -1;
}
return 0;
}
/*Esta funcion da los indices de los ejemplos que han dado distancia minima.
ConjuntoMinimo contiene los indices de los ejemplos de distancia minima,
hasta que haya un -1 (ahi acaba la lista de ejemplos)*/
TIndiceEj *BuscaKMinimos(TValorRasgo *rasgos)
{
TEjemplo EjAuxiliar;
TIndiceEj PrimerIndMin;
for (TIndiceEj i=0; i<NumRasgos && rasgos[i]!=FINALIZADOR; i++)
{
EjAuxiliar.rasgos[i]=rasgos[i];
if (i<NumRasgos-1)
EjAuxiliar.rasgos[i+1]=FINALIZADOR;
}
TEjemplo * ej=(TEjemplo * )bsearch((const void*)&EjAuxiliar,(const
void*)ejemplos,NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);
/*
TEjemplo * ej=(TEjemplo * )lfind((const void*)&EjAuxiliar,(const void*)ejemplos,(unsigned
int*)&NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);*/
if (ej!=NULL)
{
PrimerIndMin=((int32)ej-(int32)ejemplos)/(int32)(sizeof(ejemplos[0]));
}
else
C-28
Anexo C. Listado de programas
{
PrimerIndMin=BuscaMinimo(rasgos);
}
distMin=distancia(ejemplos[PrimerIndMin].rasgos,rasgos);
#if defined(__WIN32__)
TIndiceEj *ConjuntoMinimo=new TIndiceEj [NumEjemplos+1];
#else
TIndiceEj *ConjuntoMinimo=(TIndiceEj *)farmalloc (sizeof(TIndiceEj)*(NumEjemplos+1));
#endif
TIndiceEj i;
TIndiceEj j; /* falta k-NN */
for (i=PrimerIndMin, j=0; i<NumEjemplos; i++)
{
if (distancia(ejemplos[i].rasgos,rasgos)==distMin)
{
ConjuntoMinimo[j++]=i;
}
else if (ej!=NULL)
break;
}
if (ej!=NULL)
{
for (i=PrimerIndMin-1; i>=0; i--)
{
if (distancia(ejemplos[i].rasgos,rasgos)==distMin)
{
ConjuntoMinimo[j++]=i;
}
else if (ej!=NULL)
break;
}
}
if (j<=0)
assert(0);
else
ConjuntoMinimo[j]=FINALIZADOR;
return ConjuntoMinimo;
}
/*Esta función devuelve los ejemplos que han dado distancia mínima.
Soluciones: lista de ejemplos hasta que haya un finalizador en la solución
del último ejemplo*/
TEjemplo *BuscaSoluciones(TValorRasgo *rasgos)
{
TEjemplo *soluciones=new TEjemplo[NumEjemplos+1];
TIndiceEj *ConjuntoMinimo=BuscaKMinimos(rasgos);
TIndiceEj i;
for (i=0; ConjuntoMinimo[i] != FINALIZADOR; i++)
{
soluciones[i].solucion=ejemplos[ConjuntoMinimo[i]].solucion;
soluciones[i].frecuencia=ejemplos[ConjuntoMinimo[i]].frecuencia;
memcpy(soluciones[i].rasgos,ejemplos[ConjuntoMinimo[i]].rasgos,
sizeof(soluciones[i].rasgos));
}
if (i<=0)
assert(0);
else
soluciones[i].solucion=FINALIZADOR;
delete []ConjuntoMinimo;
return soluciones;
}
/*Estas funciones recorren la variable ejemplos, para dar las soluc. max y min*/
TValorSolucion CalculaMinSoluc()
{
TValorSolucion MinSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion < MinSoluc) MinSoluc = ejemplos[i].solucion;
}
return MinSoluc;
}
TValorSolucion CalculaMaxSoluc()
{
TValorSolucion MaxSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion > MaxSoluc) MaxSoluc = ejemplos[i].solucion;
}
return MaxSoluc;
}
/*A esta funci'on se le pasa un array de contadores, y devuelve el indice del
contador m'as alto*/
TValorSolucion BuscaSolMasProbable(TFrecuencia *contador,TIndiceEj rangoSoluc,TIndiceEj
minSoluc)
{
TIndiceEj i;
TIndiceEj indice=0;
TIndiceEj maximo=0;
for (i=0; i<rangoSoluc; i++)
C-29
Anexo C. Listado de programas
{
if (contador[i] > maximo)
{
indice = i+minSoluc;
maximo=contador[i];
}
}
return indice;
}
/*A esta función se le pasa una ventana de rasgos y devuelve la solución
estimada para el rasgo (letra) central. Utiliza el array de frecuencias Contador:
cada posición se corresponde con una solución (de la mín a la máx), y contiene la
frecuencia acumulada con que se da esa solución dentro del conjunto de ejemplos
que han dado distancia mínima a la ventana en estudio*/
TValorSolucion DecisionSolucion(TValorRasgo *rasgos)
{
TEjemplo *soluciones=BuscaSoluciones(rasgos);
TIndiceEj maxSoluc=CalculaMaxSoluc();
TIndiceEj minSoluc=CalculaMinSoluc();
TIndiceEj rangoSoluc=maxSoluc-minSoluc+1;
TValorSolucion resultado;
TFrecuencia *Contador=new TFrecuencia[rangoSoluc];
memset(Contador,0,rangoSoluc*sizeof(TFrecuencia)); //Inicializo el arrray Contador
TIndiceEj i;
for (i=0; soluciones[i].solucion!=FINALIZADOR; i++)
{
Contador[soluciones[i].solucion-minSoluc]+=soluciones[i].frecuencia;
}
resultado = BuscaSolMasProbable(Contador,rangoSoluc,minSoluc);
frecSolucMasProbable=Contador[resultado];
delete [] soluciones;
delete [] Contador;
return resultado;
}
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
float LeeFlotante(char *token, int i)
{
float float_aux;
if(sscanf(token,"%f",(float*)&float_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return float_aux;
}
int LeeSolucion(char *token, int i)
{
int int_aux;
if(sscanf(token,"%d",(int*)&int_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return int_aux;
}
/*Funcion que calcula el número de ejemplos (es decir, el número de líneas del
fichero de la base de datos de ejemplos*/
/*Esta funcion carga en la variable ejemplos los datos del fichero diccionario
de ejemplos (que contiene en cada linea un ejemplo (una ventana de rasgos),
una solucion y la frecuencia de ese ejemplo). Cada linea del fichero de
entrada es como sigue: nº de rasgos por ejemplo, blanco, nº de 1er rasgo,
blanco,..., solucion, blanco, frecuencia, blanco, comentario*/
TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
TEjemplo* CargaEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
char *linea=new char [1000];
NumEjemplos=CalculaNumEjemplos(directorio, NomFichero);
if (NumEjemplos<=0)
{
errorPrintf("fichero vac'io: %s",NomFichero);
C-30
Anexo C. Listado de programas
return NULL;
}
ejemplos=new TEjemplo[NumEjemplos];
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0 && i<NumEjemplos; i++)
{
if (i%1000==0)
printf("Llevo cargados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
{
TIndiceRasgos j;
char *token=linea;
token=strtok(token," ");
NumRasgos = atoi(token); //Aqui queda ya cargada la var. global
NumRasgos
token = NULL;
for (j=0; j<NumRasgos; j++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
float aux=LeeFlotante(token,i);
ejemplos[i].rasgos[j] = aux;
token=NULL;
}
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].solucion = LeeSolucion(token,i);
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].frecuencia = LeeFlotante(token,i);
if (ejemplos[i].frecuencia<=0)
{
errorPrintf("error de formato en l'inea %ld",(long)i);
}
token=strtok(NULL,"\n");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
strcpy(ejemplos[i].comentario,token);
}
else
{
break;
}
}
flhClose(fichero);
delete [] linea;
qsort(ejemplos, NumEjemplos, sizeof(ejemplos[0]),comparaEjemplos);
return ejemplos;
}
/*Esta funci'on devuelve para que se cargue en la variable global pesos los pesos
de cada rasgo desde el fichero de pesos generado anterioemente a partir de la BD,
para su posterior utilizaci'on en el c'alculo de la distancia entre ventanas de rasgos*/
TDistancia *InicializaPesos(char *directorio, char *NomFichero)
{
TDistancia *pesos=new TDistancia[NumRasgos];
TIndiceRasgos i;
TIndiceRasgos NumRasgosFichPesos;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
if (fgets(linea,1000,fichero)!=NULL)
{
char *token=linea;
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en el fichero de pesos");
}
NumRasgosFichPesos = LeeFlotante(token,1);
if (NumRasgos != NumRasgosFichPesos)
{
errorPrintf("error de formato en el fichero de pesos");
}
token = NULL;
for (i=0; i<NumRasgos; i++)
{
token=strtok(token," ");
if (token==NULL)
{
C-31
Anexo C. Listado de programas
}
FILE *fichero3=flhOpen(".\\", FicheroEstadisticasEvaluacion, "wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",FicheroEstadisticasEvaluacion);
}
for (i=0; feof(fichero2)==0; i++)
{
if (i%10==0)
printf("Llevo evaluados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero2)!=NULL)
{
TIndiceRasgos j;
char *token=linea;
token=strtok(token," ");
NumRasgosFichPruebas = atoi(token);
if (NumRasgos != NumRasgosFichPruebas)
{
errorPrintf("error de formato en el fichero de pruebas");
}
token = NULL;
for (j=0; j<NumRasgos; j++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en
errorPrintf("error de formato en el fichero de pesos");
}
pesos[i] = LeeFlotante(token,i);
token=NULL;
}
}
flhClose(fichero);
delete [] linea;
return pesos;
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==6)
{
strcpy(FicheroPruebas,argv[1]);
strcpy(FicheroBDEjemplos,argv[2]);
strcpy(FicheroPesos,argv[3]);
strcpy(FicheroEvaluacion,argv[4]);
strcpy(FicheroEstadisticasEvaluacion,argv[5]);
}
ejemplos=CargaEjemplos(".\\", FicheroBDEjemplos);
if (ejemplos!=NULL)
{
TEjemplo EjemploPrueba; //Contiene el ejemplo que se va leyendo del fichero
de pruebas
TIndiceRasgos NumRasgosFichPruebas; //Nº de rasgos que lee del fichero de pruebas
char *linea=new char [1000];
TIndiceEj contOK=0;
TIndiceEj i;
int k;
pesos = InicializaPesos(".\\",FicheroPesos);
FILE *fichero1=flhOpen(".\\", FicheroEvaluacion, "wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",FicheroEvaluacion);
}
k=fprintf(fichero1,"%s\n\n","Num_Rasgos Rasgo1 ... RasgoN Soluc_Leida
Soluc_Estimada Frec_SolMasProb Dist_Min Pal_leida");
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion);
FILE *fichero2=flhOpen(".\\", FicheroPruebas, "rt");
if (fichero2==NULL)
{
errorPrintf("falta el fichero %s",FicheroPruebas);
l'inea %d",(long)i);
}
float aux=LeeFlotante(token,i);
EjemploPrueba.rasgos[j] = aux;
token=NULL;
}
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
EjemploPrueba.solucion = LeeSolucion(token,i);
token=strtok(NULL," ");
if (token==NULL)
errorPrintf("error de formato en l'inea
%d",(long)i);
EjemploPrueba.frecuencia = LeeFlotante(token,i);
token=strtok(NULL,"\n");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
C-32
Anexo C. Listado de programas
strcpy(EjemploPrueba.comentario,token);
}
else
{
break;
}
SolucionEvaluada = DecisionSolucion(EjemploPrueba.rasgos);
k=fprintf(fichero1,"%d ", (int)NumRasgos);
if (k==EOF)
errorPrintf("error en la escritura del fichero
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisticasEvaluacion);
flhClose(fichero1);
flhClose(fichero2);
flhClose(fichero3);
delete [] linea;
delete [] pesos;
}
delete [] ejemplos;
}
%s",FicheroEvaluacion);
for (TIndiceRasgos j=0; j<NumRasgos; j++)
{
k=fprintf(fichero1,"%.0f ",
C.4.1. Módulo mixto MBL-probabilidades.
(float)EjemploPrueba.rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
if (SolucionEvaluada == EjemploPrueba.solucion)
{
contOK++;
k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s\n",
(float)EjemploPrueba.solucion,
(float)SolucionEvaluada,
(float)frecSolucMasProbable, (float)distMin,
EjemploPrueba.comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
else
{
k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s_ERROR\n",
(float)EjemploPrueba.solucion,
(float)SolucionEvaluada,
(float)frecSolucMasProbable, (float)distMin,
EjemploPrueba.comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
}
k=fprintf(fichero3,"%s\n", "Estad'sticas de la evaluaci'on:");
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisticasEvaluacion);
k=fprintf(fichero3," Tasa de aciertos (en%%): %f (%ld de
%ld)\n",(contOK/(float)i)*100,contOK,(long)i);
if (k==EOF)
/*Este evalua_prob se va a diferenciar del evalua en que aquí, si me encuentro
con un caso en el que la distancia mínima del ejemplo en estudio a uno de la BD
con la que ha entrenado no es cero (es decir, no se encuentra ese ejemplo en
la BD), se dará como solución la más probable*/
#include <assert.h>
#include "silabica.h"
#include <string.h>
#include <stdio.h>
#include <values.h>
#include <math.h>
#include <mem.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "tildes.h"
TEjemplo *ejemplos;
TIndiceEj NumEjemplos; //Nº de ejemplos de la BD de entrenamiento
TDistancia *pesos;
TIndiceRasgos NumRasgos = 0; //Variable con el n'umero de rasgos que lee desde el fichero BD de
ejemplos
TValorSolucion SolucionEvaluada;
TValorSolucion SolucionMasProbable; //Sol. más probable en el fich. de entren. (para la pal. en
estudio)
TFrecuencia frecSolucMasProbable=0; //Guarda la frec. de la soluc + probable para cada vantana
evaluada
TDistancia distMin=0; //Guarda la dist. min. de cada ventana de rasgos a los ej de dist mínima
char FicheroPruebas[MAXPATH]="fich_ej_prue.dic"; //Fichero con todos las palabras para evaluar
(pasado por el traductor)
char FicheroBDEjemplos[MAXPATH]="bd_ej.dic";//Fichero con ejemplos y soluciones
char FicheroPesos[MAXPATH]="pesos.dic"; //Fichero con los pesos
char FicheroEvaluacion[MAXPATH]="evaluacion_prob.est"; //Fichero con todas las ventanas
evaluadas.
/*El formato de evaluacion.est es: nºrasgos, 1er rasgo,...,último rasgo, solución según se
C-33
Anexo C. Listado de programas
TValorRasgo *vent=(TValorRasgo *)x;
TEjemplo *ej=(TEjemplo *)y;
for (int i=0; i<NumRasgos; i++)
{
if (vent[i]>ej->rasgos[i])
return 1;
else if (vent[i]<ej->rasgos[i])
return -1;
}
return 0;
ha leído del texto de pruebas, solucion estimada por el evaluador, frecuencia acumulada
de lo/s ejemplo/s de dist. mínima cuya solución se ha tomado como la más probable,
distancia mínima a lo/s ejemplo/s de dist. mínima y comentario (palabra leída del texto
de pruebas, de la que se ha obtenido la ventana en estudio*/
char FicheroEstadisticasEvaluacion[MAXPATH]="estadis_prob.est"; // Fichero con las estad'isticas
char FicheroProbEntren[MAXPATH]="prob_entren.dic"; // Fichero con las prob. de cada solución
TDistancia DistanciaRasgos(TValorRasgo a, TValorRasgo b)
{
if (a==b)
return 0;
else
return 1;
}
TDistancia distancia(TValorRasgo *ejemp1, TValorRasgo *ejemp2)
{
TIndiceRasgos i;
TDistancia Distancia;
for (i=0,Distancia=0; i<NumRasgos; i++)
{
Distancia+=pesos[i]*DistanciaRasgos(ejemp1[i],ejemp2[i]);
}
return Distancia;
}
/*Esta funcion busca el primer ejemplo de distancia minima*/
TIndiceEj BuscaMinimo(TValorRasgo *rasgos)
{
TDistancia distMin=MAXFLOAT;
TIndiceEj indMin=-MAXLONG;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (distancia(ejemplos[i].rasgos,rasgos)<distMin)
{
distMin=distancia(ejemplos[i].rasgos,rasgos);
indMin=i;
}
}
assert(indMin>=0);
return indMin;
}
int comparaEjemplos(const void *x, const void *y)
{
}
/*Esta funcion da los indices de los ejemplos que han dado distancia minima.
ConjuntoMinimo contiene los indices de los ejemplos de distancia minima,
hasta que haya un -1 (ahi acaba la lista de ejemplos)*/
TIndiceEj *BuscaKMinimos(TValorRasgo *rasgos)
{
TEjemplo EjAuxiliar;
TIndiceEj PrimerIndMin;
for (TIndiceEj i=0; i<NumRasgos && rasgos[i]!=FINALIZADOR; i++)
{
EjAuxiliar.rasgos[i]=rasgos[i];
if (i<NumRasgos-1)
EjAuxiliar.rasgos[i+1]=FINALIZADOR;
}
TEjemplo * ej=(TEjemplo * )bsearch((const void*)&EjAuxiliar,(const
void*)ejemplos,NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);
/*
TEjemplo * ej=(TEjemplo * )lfind((const void*)&EjAuxiliar,(const void*)ejemplos,(unsigned
int*)&NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);*/
if (ej!=NULL)
{
PrimerIndMin=((int32)ej-(int32)ejemplos)/(int32)(sizeof(ejemplos[0]));
}
else
{
PrimerIndMin=BuscaMinimo(rasgos);
}
distMin=distancia(ejemplos[PrimerIndMin].rasgos,rasgos);
#if defined(__WIN32__)
TIndiceEj *ConjuntoMinimo=new TIndiceEj [NumEjemplos+1];
#else
TIndiceEj *ConjuntoMinimo=(TIndiceEj *)farmalloc (sizeof(TIndiceEj)*(NumEjemplos+1));
#endif
TIndiceEj i;
TIndiceEj j; /* falta k-NN */
for (i=PrimerIndMin, j=0; i<NumEjemplos; i++)
{
C-34
Anexo C. Listado de programas
if (distancia(ejemplos[i].rasgos,rasgos)==distMin)
{
ConjuntoMinimo[j++]=i;
}
else if (ej!=NULL)
break;
}
if (ej!=NULL)
{
for (i=PrimerIndMin-1; i>=0; i--)
{
if (distancia(ejemplos[i].rasgos,rasgos)==distMin)
{
ConjuntoMinimo[j++]=i;
}
else if (ej!=NULL)
break;
}
}
if (j<=0)
assert(0);
else
ConjuntoMinimo[j]=FINALIZADOR;
return ConjuntoMinimo;
}
/*Esta función devuelve los ejemplos que han dado distancia mínima.
Soluciones: lista de ejemplos hasta que haya un finalizador en la solución
del último ejemplo*/
TEjemplo *BuscaSoluciones(TValorRasgo *rasgos)
{
TEjemplo *soluciones=new TEjemplo[NumEjemplos+1];
TIndiceEj *ConjuntoMinimo=BuscaKMinimos(rasgos);
TIndiceEj i;
for (i=0; ConjuntoMinimo[i] != FINALIZADOR; i++)
{
soluciones[i].solucion=ejemplos[ConjuntoMinimo[i]].solucion;
soluciones[i].frecuencia=ejemplos[ConjuntoMinimo[i]].frecuencia;
memcpy(soluciones[i].rasgos,ejemplos[ConjuntoMinimo[i]].rasgos,
sizeof(soluciones[i].rasgos));
}
if (i<=0)
assert(0);
else
soluciones[i].solucion=FINALIZADOR;
delete []ConjuntoMinimo;
return soluciones;
}
/*Estas funciones recorren la variable ejemplos, para dar las soluc. max y min*/
TValorSolucion CalculaMinSoluc()
{
TValorSolucion MinSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion < MinSoluc) MinSoluc = ejemplos[i].solucion;
}
return MinSoluc;
}
TValorSolucion CalculaMaxSoluc()
{
TValorSolucion MaxSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion > MaxSoluc) MaxSoluc = ejemplos[i].solucion;
}
return MaxSoluc;
}
/*A esta funci'on se le pasa un array de contadores, y devuelve el indice del
contador m'as alto*/
TValorSolucion BuscaSolMasProbable(TFrecuencia *contador,TIndiceEj rangoSoluc,TIndiceEj
minSoluc)
{
TIndiceEj i;
TIndiceEj indice=0;
TIndiceEj maximo=0;
for (i=0; i<rangoSoluc; i++)
{
if (contador[i] > maximo)
{
indice = i+minSoluc;
maximo=contador[i];
}
}
return indice;
}
/*A esta función se le pasa una ventana de rasgos y devuelve la solución
estimada para el rasgo (letra) central. Utiliza el array de frecuencias Contador:
cada posición se corresponde con una solución (de la mín a la máx), y contiene la
C-35
Anexo C. Listado de programas
frecuencia acumulada con que se da esa solución dentro del conjunto de ejemplos
que han dado distancia mínima a la ventana en estudio*/
TValorSolucion DecisionSolucion(TValorRasgo *rasgos)
{
TEjemplo *soluciones=BuscaSoluciones(rasgos);
TIndiceEj maxSoluc=CalculaMaxSoluc();
TIndiceEj minSoluc=CalculaMinSoluc();
TIndiceEj rangoSoluc=maxSoluc-minSoluc+1;
TValorSolucion resultado;
TFrecuencia *Contador=new TFrecuencia[rangoSoluc];
memset(Contador,0,rangoSoluc*sizeof(TFrecuencia)); //Inicializo el arrray Contador
TIndiceEj i;
for (i=0; soluciones[i].solucion!=FINALIZADOR; i++)
{
Contador[soluciones[i].solucion-minSoluc]+=soluciones[i].frecuencia;
}
resultado = BuscaSolMasProbable(Contador,rangoSoluc,minSoluc);
frecSolucMasProbable=Contador[resultado];
delete [] soluciones;
delete [] Contador;
return resultado;
}
/*Funcion que calcula el número de ejemplos (es decir, el número de líneas del
fichero de la base de datos de ejemplos*/
TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
float LeeFlotante(char *token, int i)
{
float float_aux;
if(sscanf(token,"%f",(float*)&float_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return float_aux;
}
int LeeSolucion(char *token, int i)
{
int int_aux;
if(sscanf(token,"%d",(int*)&int_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return int_aux;
}
/*Esta funcion carga en la variable ejemplos los datos del fichero diccionario
de ejemplos (que contiene en cada linea un ejemplo (una ventana de rasgos),
una solucion y la frecuencia de ese ejemplo). Cada linea del fichero de
entrada es como sigue: nº de rasgos por ejemplo, blanco, nº de 1er rasgo,
blanco,..., solucion, blanco, frecuencia, blanco, comentario*/
TEjemplo* CargaEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
char *linea=new char [1000];
NumEjemplos=CalculaNumEjemplos(directorio, NomFichero);
if (NumEjemplos<=0)
{
errorPrintf("fichero vac'io: %s",NomFichero);
return NULL;
}
ejemplos=new TEjemplo[NumEjemplos];
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0 && i<NumEjemplos; i++)
{
if (i%100==0)
printf("Llevo cargados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
{
C-36
Anexo C. Listado de programas
TIndiceRasgos j;
char *token=linea;
token=strtok(token," ");
NumRasgos = atoi(token); //Aqui queda ya cargada la var. global
NumRasgos
token = NULL;
for (j=0; j<NumRasgos; j++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
float aux=LeeFlotante(token,i);
ejemplos[i].rasgos[j] = aux;
token=NULL;
}
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].solucion = LeeSolucion(token,i);
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].frecuencia = LeeFlotante(token,i);
if (ejemplos[i].frecuencia<=0)
{
errorPrintf("error de formato en l'inea %ld",(long)i);
}
token=strtok(NULL,"\n");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
strcpy(ejemplos[i].comentario,token);
}
else
{
break;
}
}
flhClose(fichero);
delete [] linea;
qsort(ejemplos, NumEjemplos, sizeof(ejemplos[0]),comparaEjemplos);
return ejemplos;
}
/*Esta funci'on devuelve para que se cargue en la variable global pesos los pesos
de cada rasgo desde el fichero de pesos generado anterioemente a partir de la BD,
para su posterior utilizaci'on en el c'alculo de la distancia entre ventanas de rasgos*/
TDistancia *InicializaPesos(char *directorio, char *NomFichero)
{
TDistancia *pesos=new TDistancia[NumRasgos];
TIndiceRasgos i;
TIndiceRasgos NumRasgosFichPesos;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
if (fgets(linea,1000,fichero)!=NULL)
{
char *token=linea;
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en el fichero de pesos");
}
NumRasgosFichPesos = LeeFlotante(token,1);
if (NumRasgos != NumRasgosFichPesos)
{
errorPrintf("error de formato en el fichero de pesos");
}
token = NULL;
for (i=0; i<NumRasgos; i++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en el fichero de pesos");
}
pesos[i] = LeeFlotante(token,i);
token=NULL;
}
}
flhClose(fichero);
delete [] linea;
return pesos;
}
/*Esta función calcula cuál de las 2 soluciones (acentuada o no acentuada) es la más
C-37
Anexo C. Listado de programas
probable para la palabra ambigua que se está evaluando, a partir del fichero
de probabilidades prob_entren.dic*/
TValorSolucion CalculaSolMasProbEntren(char *directorio, char *NomFichero)
{
TValorSolucion solucion;
TIndiceEj ContAcen=0;
TIndiceEj ContDesacen=0;
char *linea=new char [1000];
char *token;
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
if (fgets(linea,1000,fichero)!=NULL)
{
token=linea;
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("Error de formato en el fichero de probabilidades");
}
ContAcen = LeeFlotante(token,1);
if (ContAcen < 0)
{
errorPrintf("error de formato en el fichero de probabilidades");
}
token = NULL;
}
if (fgets(linea,1000,fichero)!=NULL)
{
token=linea;
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("Error de formato en el fichero de probabilidades");
}
ContDesacen = LeeFlotante(token,1);
if (ContDesacen < 0)
{
errorPrintf("error de formato en el fichero de probabilidades");
}
}
if (ContAcen>ContDesacen)
solucion = ES_INTERROG;
else if (ContAcen<ContDesacen)
solucion = NO_ES_INTERROG;
else
solucion = INDEFINIDO;
flhClose(fichero);
delete [] linea;
return solucion;
}
void main(int argc,char *argv[])
{
if (argc==1)
{
}
else if (argc==6)
{
strcpy(FicheroPruebas,argv[1]);
strcpy(FicheroBDEjemplos,argv[2]);
strcpy(FicheroPesos,argv[3]);
strcpy(FicheroEvaluacion,argv[4]);
strcpy(FicheroEstadisticasEvaluacion,argv[5]);
}
ejemplos=CargaEjemplos(DIRECTORIO, FicheroBDEjemplos);
if (ejemplos!=NULL)
{
TEjemplo EjemploPrueba; //Contiene el ejemplo que se va leyendo del fichero
de pruebas
TIndiceRasgos NumRasgosFichPruebas; //Nº de rasgos que lee del fichero de pruebas
char *linea=new char [1000];
TIndiceEj contOK=0;
TIndiceEj i;
int k;
pesos = InicializaPesos(DIRECTORIO,FicheroPesos);
SolucionMasProbable = CalculaSolMasProbEntren(DIRECTORIO, FicheroProbEntren);
FILE *fichero1=flhOpen(DIRECTORIO, FicheroEvaluacion, "wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",FicheroEvaluacion);
}
k=fprintf(fichero1,"%s\n\n","Num_Rasgos Rasgo1 ... RasgoN Soluc_Leida
Soluc_Estimada Frec_SolMasProb Dist_Min Pal_leida");
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion);
FILE *fichero2=flhOpen(DIRECTORIO, FicheroPruebas, "rt");
if (fichero2==NULL)
{
errorPrintf("falta el fichero %s",FicheroPruebas);
}
FILE *fichero3=flhOpen(DIRECTORIO, FicheroEstadisticasEvaluacion, "wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",FicheroEstadisticasEvaluacion);
}
C-38
Anexo C. Listado de programas
for (i=0; feof(fichero2)==0; i++)
{
if (i%100==0)
printf("Llevo evaluados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero2)!=NULL)
{
TIndiceRasgos j;
char *token=linea;
token=strtok(token," ");
NumRasgosFichPruebas = atoi(token);
if (NumRasgos != NumRasgosFichPruebas)
{
errorPrintf("error de formato en el fichero de pruebas");
}
token = NULL;
for (j=0; j<NumRasgos; j++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en
l'inea %d",(long)i);
}
float aux=LeeFlotante(token,i);
EjemploPrueba.rasgos[j] = aux;
token=NULL;
}
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
EjemploPrueba.solucion = LeeSolucion(token,i);
token=strtok(NULL," ");
if (token==NULL)
errorPrintf("error de formato en l'inea
%d",(long)i);
EjemploPrueba.frecuencia = LeeFlotante(token,i);
token=strtok(NULL,"\n");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
strcpy(EjemploPrueba.comentario,token);
}
else
{
break;
}
SolucionEvaluada = DecisionSolucion(EjemploPrueba.rasgos);
if (distMin>0 && SolucionMasProbable!=INDEFINIDO)
{
SolucionEvaluada = SolucionMasProbable;
}
k=fprintf(fichero1,"%d ", (int)NumRasgos);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
for (TIndiceRasgos j=0; j<NumRasgos; j++)
{
k=fprintf(fichero1,"%.0f ",
(float)EjemploPrueba.rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
if (SolucionEvaluada == EjemploPrueba.solucion)
{
contOK++;
k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s\n",
(float)EjemploPrueba.solucion,
(float)SolucionEvaluada,
(float)frecSolucMasProbable, (float)distMin,
EjemploPrueba.comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
else
{
k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s_ERROR\n",
(float)EjemploPrueba.solucion,
(float)SolucionEvaluada,
(float)frecSolucMasProbable, (float)distMin,
EjemploPrueba.comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
}
k=fprintf(fichero3,"%s\n", "Estad'sticas de la evaluaci'on:");
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisticasEvaluacion);
k=fprintf(fichero3," Tasa de aciertos (en%%): %f (%ld de
%ld)\n",(contOK/(float)i)*100,contOK,(long)i);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisticasEvaluacion);
flhClose(fichero1);
C-39
Anexo C. Listado de programas
flhClose(fichero2);
flhClose(fichero3);
delete [] linea;
delete [] pesos;
}
delete [] ejemplos;
}
C.4.2. Módulo de evaluación para tareas de tildado a
partir de la categorización.
#include <assert.h>
#include "silabica.h"
#include <string.h>
#include <stdio.h>
#include <values.h>
#include <math.h>
#include <mem.h>
#include "portable.h"
#include "portimpr.h"
#include "flh.h"
#include "tildes.h"
TEjemplo *ejemplos;
TPalabraCateg *rasgos;
TPalabraCateg *rasgos2; //Palabras-categorías del sin tildar
TIndiceEj NumEjemplos; //Nº de ejemplos de la BD de entrenamiento
TIndiceEj NumPalabrasCateg = 0; /*Variable con el nº de palabras distintas que se van
encontrando en el fichero de rasgos*/
TIndiceEj NumPalabrasCateg2 = 0; /*Variable con el nº de palabras distintas que se van
encontrando en el fichero de rasgos al cargarlas sin tilde*/
TIndiceEj ContPalabrasCateg = 0; //Variable con el nº de palabras de los ficheros de cat.
TIndiceEj NumEjemplosCategNoEncont = 0; //Variable con el nº ejemplos no encontrados en el fich
de rasgos
TDistancia *pesos;
TIndiceRasgos NumRasgos = 0; //Variable con el n'umero de rasgos que lee desde el fichero BD de
ejemplos
TValorSolucion SolucionEvaluada;
TFrecuencia frecSolucMasProbable=0; //Guarda la frec. de la soluc + probable para cada vantana
evaluada
TDistancia distMin=0; //Guarda la dist. min. de cada ventana de rasgos a los ej de dist mínima
char FicheroPruebas[MAXPATH]="fich_ej_prue.dic"; //Fichero con todos las palabras para evaluar
(pasado por el traductor)
char FicheroBDEjemplos[MAXPATH]="bd_ej.dic";//Fichero con ejemplos y soluciones
char FicheroPesos[MAXPATH]="pesos.dic"; //Fichero con los pesos
char FicheroRasgos[MAXPATH]="fich_rasgos.dic"; //Fichero con los rasgos (palabra y su cat.) con
los q entrena
char FicheroRasgosPrue[MAXPATH]="fich_rasgos_prue.dic"; //Fichero con los rasgos (palabra y su
cat.) que evalua
char FicheroEvaluacion[MAXPATH]="evaluacion.est"; //Fichero con todas las ventanas evaluadas.
/*El formato de evaluacion.est es: nºrasgos, 1er rasgo,...,último rasgo, solución según se
ha leído del texto de pruebas, solucion estimada por el evaluador, frecuencia acumulada
de lo/s ejemplo/s de dist. mínima cuya solución se ha tomado como la más probable,
distancia mínima a lo/s ejemplo/s de dist. mínima y comentario (palabra leída del texto
de pruebas, de la que se ha obtenido la ventana en estudio*/
char FicheroEstadisticasEvaluacion[MAXPATH]="estadis.est"; // Fichero con las estad'isticas
char FicheroErroresTildado[MAXPATH]="errores_tildado.est"; /*Fichero con las palabras
en las que se ha errado la estimación del tildado y sin embargo se acertó en su
categorización*/
TDistancia DistanciaRasgos(TValorRasgo a, TValorRasgo b)
{
if (a==b)
return 0;
else
return 1;
}
TDistancia distancia(TValorRasgo *ejemp1, TValorRasgo *ejemp2)
{
TIndiceRasgos i;
TDistancia Distancia;
for (i=0,Distancia=0; i<NumRasgos; i++)
{
Distancia+=pesos[i]*DistanciaRasgos(ejemp1[i],ejemp2[i]);
}
return Distancia;
}
/*Esta funcion busca el primer ejemplo de distancia minima*/
TIndiceEj BuscaMinimo(TValorRasgo *rasgos)
{
TDistancia distMin=MAXFLOAT;
TIndiceEj indMin=-MAXLONG;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (distancia(ejemplos[i].rasgos,rasgos)<distMin)
{
distMin=distancia(ejemplos[i].rasgos,rasgos);
indMin=i;
C-40
Anexo C. Listado de programas
}
}
assert(indMin>=0);
return indMin;
}
int comparaEjemplos(const void *x, const void *y)
{
TValorRasgo *vent=(TValorRasgo *)x;
TEjemplo *ej=(TEjemplo *)y;
for (int i=0; i<NumRasgos; i++)
{
if (vent[i]>ej->rasgos[i])
return 1;
else if (vent[i]<ej->rasgos[i])
return -1;
}
return 0;
}
/*Esta funcion da los indices de los ejemplos que han dado distancia minima.
ConjuntoMinimo contiene los indices de los ejemplos de distancia minima,
hasta que haya un -1 (ahi acaba la lista de ejemplos)*/
TIndiceEj *BuscaKMinimos(TValorRasgo *rasgos)
{
TEjemplo EjAuxiliar;
TIndiceEj PrimerIndMin;
for (TIndiceEj i=0; i<NumRasgos && rasgos[i]!=FINALIZADOR; i++)
{
EjAuxiliar.rasgos[i]=rasgos[i];
if (i<NumRasgos-1)
EjAuxiliar.rasgos[i+1]=FINALIZADOR;
}
TEjemplo * ej=(TEjemplo * )bsearch((const void*)&EjAuxiliar,(const
void*)ejemplos,NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);
/*
TEjemplo * ej=(TEjemplo * )lfind((const void*)&EjAuxiliar,(const void*)ejemplos,(unsigned
int*)&NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);*/
if (ej!=NULL)
{
PrimerIndMin=((int32)ej-(int32)ejemplos)/(int32)(sizeof(ejemplos[0]));
}
else
{
PrimerIndMin=BuscaMinimo(rasgos);
}
distMin=distancia(ejemplos[PrimerIndMin].rasgos,rasgos);
#if defined(__WIN32__)
TIndiceEj *ConjuntoMinimo=new TIndiceEj [NumEjemplos+1];
#else
TIndiceEj *ConjuntoMinimo=(TIndiceEj *)farmalloc (sizeof(TIndiceEj)*(NumEjemplos+1));
#endif
TIndiceEj i;
TIndiceEj j; /* falta k-NN */
for (i=PrimerIndMin, j=0; i<NumEjemplos; i++)
{
if (distancia(ejemplos[i].rasgos,rasgos)==distMin)
{
ConjuntoMinimo[j++]=i;
}
else if (ej!=NULL)
break;
}
if (ej!=NULL)
{
for (i=PrimerIndMin-1; i>=0; i--)
{
if (distancia(ejemplos[i].rasgos,rasgos)==distMin)
{
ConjuntoMinimo[j++]=i;
}
else if (ej!=NULL)
break;
}
}
if (j<=0)
assert(0);
else
ConjuntoMinimo[j]=FINALIZADOR;
return ConjuntoMinimo;
}
/*Esta función devuelve los ejemplos que han dado distancia mínima.
Soluciones: lista de ejemplos hasta que haya un finalizador en la solución
del último ejemplo*/
TEjemplo *BuscaSoluciones(TValorRasgo *rasgos)
{
TEjemplo *soluciones=new TEjemplo[NumEjemplos+1];
TIndiceEj *ConjuntoMinimo=BuscaKMinimos(rasgos);
TIndiceEj i;
for (i=0; ConjuntoMinimo[i] != FINALIZADOR; i++)
{
soluciones[i].solucion=ejemplos[ConjuntoMinimo[i]].solucion;
soluciones[i].frecuencia=ejemplos[ConjuntoMinimo[i]].frecuencia;
memcpy(soluciones[i].rasgos,ejemplos[ConjuntoMinimo[i]].rasgos,
C-41
Anexo C. Listado de programas
sizeof(soluciones[i].rasgos));
}
if (i<=0)
assert(0);
}
}
return indice;
}
else
soluciones[i].solucion=FINALIZADOR;
delete []ConjuntoMinimo;
return soluciones;
}
/*A esta función se le pasa una ventana de rasgos y devuelve la solución
estimada para el rasgo (letra) central. Utiliza el array de frecuencias Contador:
cada posición se corresponde con una solución (de la mín a la máx), y contiene la
frecuencia acumulada con que se da esa solución dentro del conjunto de ejemplos
que han dado distancia mínima a la ventana en estudio*/
/*Estas funciones recorren la variable ejemplos, para dar las soluc. max y min*/
TValorSolucion CalculaMinSoluc()
{
TValorSolucion MinSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion < MinSoluc) MinSoluc = ejemplos[i].solucion;
}
return MinSoluc;
}
TValorSolucion CalculaMaxSoluc()
{
TValorSolucion MaxSoluc = ejemplos[0].solucion;
TIndiceEj i;
for (i=0; i<NumEjemplos; i++)
{
if (ejemplos[i].solucion > MaxSoluc) MaxSoluc = ejemplos[i].solucion;
}
return MaxSoluc;
}
/*A esta funci'on se le pasa un array de contadores, y devuelve el indice del
contador m'as alto*/
TValorSolucion BuscaSolMasProbable(TFrecuencia *contador,TIndiceEj rangoSoluc,TIndiceEj
minSoluc)
{
TIndiceEj i;
TIndiceEj indice=0;
TIndiceEj maximo=0;
for (i=0; i<rangoSoluc; i++)
{
if (contador[i] > maximo)
{
indice = i+minSoluc;
maximo=contador[i];
TValorSolucion DecisionSolucion(TValorRasgo *rasgos)
{
TEjemplo *soluciones=BuscaSoluciones(rasgos);
TIndiceEj maxSoluc=CalculaMaxSoluc();
TIndiceEj minSoluc=CalculaMinSoluc();
TIndiceEj rangoSoluc=maxSoluc-minSoluc+1;
TValorSolucion resultado;
TFrecuencia *Contador=new TFrecuencia[rangoSoluc];
memset(Contador,0,rangoSoluc*sizeof(TFrecuencia)); //Inicializo el arrray Contador
TIndiceEj i;
for (i=0; soluciones[i].solucion!=FINALIZADOR; i++)
{
Contador[soluciones[i].solucion-minSoluc]+=soluciones[i].frecuencia;
}
resultado = BuscaSolMasProbable(Contador,rangoSoluc,minSoluc);
frecSolucMasProbable=Contador[resultado];
delete [] soluciones;
delete [] Contador;
return resultado;
}
/*Funcion que calcula el número de ejemplos (es decir, el número de líneas del
fichero de la base de datos de ejemplos*/
TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=0;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (fgets(linea,1000,fichero)!=NULL)
C-42
Anexo C. Listado de programas
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
float LeeFlotante(char *token, int i)
{
float float_aux;
if(sscanf(token,"%f",(float*)&float_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return float_aux;
}
int LeeSolucion(char *token, int i)
{
int int_aux;
if(sscanf(token,"%d",(int*)&int_aux)!=1)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
return int_aux;
}
/*Esta funcion carga en la variable ejemplos los datos del fichero diccionario
de ejemplos (que contiene en cada linea un ejemplo (una ventana de rasgos),
una solucion y la frecuencia de ese ejemplo). Cada linea del fichero de
entrada es como sigue: nº de rasgos por ejemplo, blanco, nº de 1er rasgo,
blanco,..., solucion, blanco, frecuencia, blanco, comentario*/
TEjemplo* CargaEjemplos(char *directorio, char *NomFichero)
{
TIndiceEj i;
char *linea=new char [1000];
NumEjemplos=CalculaNumEjemplos(directorio, NomFichero);
if (NumEjemplos<=0)
{
errorPrintf("fichero vac'io: %s",NomFichero);
return NULL;
}
ejemplos=new TEjemplo[NumEjemplos];
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0 && i<NumEjemplos; i++)
{
if (i%100==0)
printf("Llevo cargados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
{
TIndiceRasgos j;
char *token=linea;
token=strtok(token," ");
NumRasgos = atoi(token); //Aqui queda ya cargada la var. global
NumRasgos
token = NULL;
for (j=0; j<NumRasgos; j++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
float aux=LeeFlotante(token,i);
ejemplos[i].rasgos[j] = aux;
token=NULL;
}
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].solucion = LeeSolucion(token,i);
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
ejemplos[i].frecuencia = LeeFlotante(token,i);
if (ejemplos[i].frecuencia<=0)
{
errorPrintf("error de formato en l'inea %ld",(long)i);
}
token=strtok(NULL,"\n");
if (token==NULL)
{
errorPrintf("error de formato en l'inea %d",(long)i);
}
strcpy(ejemplos[i].comentario,token);
}
C-43
Anexo C. Listado de programas
else
{
break;
}
}
flhClose(fichero);
delete [] linea;
qsort(ejemplos, NumEjemplos, sizeof(ejemplos[0]),comparaEjemplos);
return ejemplos;
}
/*Esta funci'on devuelve para que se cargue en la variable global pesos los pesos
de cada rasgo desde el fichero de pesos generado anterioemente a partir de la BD,
para su posterior utilizaci'on en el c'alculo de la distancia entre ventanas de rasgos*/
TDistancia *InicializaPesos(char *directorio, char *NomFichero)
{
TDistancia *pesos=new TDistancia[NumRasgos];
TIndiceRasgos i;
TIndiceRasgos NumRasgosFichPesos;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio, NomFichero, "rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
if (fgets(linea,1000,fichero)!=NULL)
{
char *token=linea;
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en el fichero de pesos");
}
NumRasgosFichPesos = LeeFlotante(token,1);
if (NumRasgos != NumRasgosFichPesos)
{
errorPrintf("error de formato en el fichero de pesos");
}
token = NULL;
for (i=0; i<NumRasgos; i++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en el fichero de pesos");
}
pesos[i] = LeeFlotante(token,i);
token=NULL;
}
}
flhClose(fichero);
delete [] linea;
return pesos;
}
/*Esta función devuelve la palabra leida del fich. de rasgos, junto con su categ.*/
TCategoria LeePalabraFichRasgos(FILE *fichero, char *pal)
{
char linea[1000];
char cat[40];
char *punt;
int i;
if (fgets(linea,1000,fichero)!=NULL)
{
punt=strtok(linea, " ");
if (punt==NULL)
errorPrintf("Error de formato en el fichero de rasgos");
strcpy(pal,punt);
punt=NULL;
punt=strtok(punt, "\n");
if (punt==NULL)
errorPrintf("Error de formato en el fichero de rasgos");
strcpy(cat,punt);
}
switch (cat[0])
{
case '0':
return VERBO;
case '1':
return NOMBRE;
case '2':
return ADJETIVO;
case '3':
return ADVERBIO;
case '4':
return PRONOMBRE;
case '5':
return PREPOSICION;
case '6':
return ARTICULO;
case '7':
return CONJUNCION;
case '8':
return INTERJECCION;
case '9':
return MISCELANEA;
default:
return DESCONOCIDO;
C-44
Anexo C. Listado de programas
}
}
/*Esta función pone todo en minúsculas la palabra pasada*/
void PonEnMins(const char*pal,char *pal_aux)
{
int LongPal=strlen(pal);
strcpy(pal_aux,pal);
for (int i=0; i<LongPal; i++)
{
pal_aux[i]=AnsiTolower(pal[i]);
}
}
char elimina_tilde(char car)
{
switch (car)
{
case 'á':
car = 'a';
break;
case 'é':
car = 'e';
break;
case 'í':
car = 'i';
break;
case 'ó':
car = 'o';
break;
case 'ú':
car = 'u';
break;
}
return car;
}
TPalabraCateg *CargaRasgos(char *directorio, char *NomFichero1, char *NomFichero2)
{
char *palabra=new char [40];
TCategoria categoria;
TIndiceEj j;
TIndiceRasgos l;
rasgos=new TPalabraCateg[ContPalabrasCateg];
FILE *fichero=flhOpen(directorio,NomFichero1,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero1);
}
printf("Cargando las palabras-categoría...\n");
for (j=0; feof(fichero)==0; j++)
{
categoria=LeePalabraFichRasgos(fichero,palabra);
if (NumPalabrasCateg%1000==0)
printf("Llevo cargadas en memoria %ld palabrascategor'ia\n",(long)NumPalabrasCateg);
strcpy(rasgos[NumPalabrasCateg].palabra,palabra);
rasgos[NumPalabrasCateg].cat=categoria;
NumPalabrasCateg++;
}
flhClose(fichero);
fichero=flhOpen(directorio,NomFichero2,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero2);
}
printf("Cargando las palabras-categoría...\n");
for (j=0; feof(fichero)==0; j++)
{
categoria=LeePalabraFichRasgos(fichero,palabra);
if (NumPalabrasCateg%1000==0)
printf("Llevo cargadas en memoria %ld palabrascategor'ia\n",(long)NumPalabrasCateg);
strcpy(rasgos[NumPalabrasCateg].palabra,palabra);
rasgos[NumPalabrasCateg].cat=categoria;
NumPalabrasCateg++;
}
flhClose(fichero);
delete [] palabra;
return rasgos;
}
/*Esta función carga los rasgos sin tilde en memoria (variable rsgos2), para su
posterior evaluación*/
TPalabraCateg *CargaRasgos2(char *directorio, char *NomFichero1, char *NomFichero2)
{
char *palabra=new char [40];
char *pal_aux=new char [40];
TCategoria categoria;
TIndiceEj j;
TIndiceRasgos l;
int i,LongPal;
rasgos2=new TPalabraCateg[ContPalabrasCateg];
FILE *fichero=flhOpen(directorio,NomFichero1,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero1);
C-45
Anexo C. Listado de programas
}
printf("Cargando las palabras-categoría sin tildes...\n");
for (j=0; feof(fichero)==0; j++)
{
categoria=LeePalabraFichRasgos(fichero,palabra);
if (NumPalabrasCateg2%1000==0)
printf("Llevo cargadas en memoria %ld palabrascategor'ia\n",(long)NumPalabrasCateg2);
strcpy(pal_aux,palabra);
LongPal=strlen(pal_aux);
for (i=0; i<LongPal; i++)
{
pal_aux[i]=elimina_tilde(pal_aux[i]);
}
strcpy(rasgos2[NumPalabrasCateg2].palabra,pal_aux);
rasgos2[NumPalabrasCateg2].cat=categoria;
NumPalabrasCateg2++;
}
flhClose(fichero);
fichero=flhOpen(directorio,NomFichero2,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero2);
}
printf("Cargando las palabras-categoría...\n");
for (j=0; feof(fichero)==0; j++)
{
categoria=LeePalabraFichRasgos(fichero,palabra);
if (NumPalabrasCateg2%1000==0)
printf("Llevo cargadas en memoria %ld palabrascategor'ia\n",(long)NumPalabrasCateg2);
strcpy(pal_aux,palabra);
LongPal=strlen(pal_aux);
for (i=0; i<LongPal; i++)
{
pal_aux[i]=elimina_tilde(pal_aux[i]);
}
strcpy(rasgos2[NumPalabrasCateg2].palabra,pal_aux);
rasgos2[NumPalabrasCateg2].cat=categoria;
NumPalabrasCateg2++;
}
flhClose(fichero);
delete [] palabra;
delete [] pal_aux;
return rasgos2;
}
/*Si devuelve 0; función no tildada. Si no, devuelve la posic de la tilde (1,2,...)*/
int CalculaPosicionTilde(char * pal)
{
int LongPal=strlen(pal);
int posicTilde=0;
for (int i=0; i<LongPal; i++)
{
switch (pal[i])
{
case 'á': case 'é': case 'í': case 'ó': case 'ú':
return (i+1);
}
}
return 0;
}
/*Esta función nos indica, una vez evaluada la solución (categoría) estimada para un ejemplo
(que se pasa como parámetro), si a partir de dicha categoría se acertaría a la
hora de deducir el tildado de la palabra del ejemplo*/
bool EvaluaTildesCat(TEjemplo ejemplo,TValorSolucion solucion)
{
int i;
TIndiceEj j;
char *pal_aux=new char [40];
int posicTilde_ej=CalculaPosicionTilde(ejemplo.comentario);
int posicTilde_rasgo1=0;
int posicTilde_rasgo2=0;
bool acierto=true;
bool pal_encontrada=false; //Para saber si ha encontrado el ejemplo entre los rasgos
bool primera_vez=true;
int longPal=strlen(ejemplo.comentario);
strcpy(pal_aux,ejemplo.comentario);
for (i=0; i<longPal; i++)
{
pal_aux[i]=elimina_tilde(pal_aux[i]);
}
for (j=0; j<NumPalabrasCateg2; j++)
{
if (strcmp(pal_aux,rasgos2[j].palabra)==0)
{
pal_encontrada=true;
if ((solucion==ES_VERBO&&rasgos2[j].cat==VERBO) ||
(solucion==ES_NOMBRE&&rasgos2[j].cat==NOMBRE))
{
if (primera_vez==true)
{
posicTilde_rasgo2=CalculaPosicionTilde(rasgos[j].palabra);
primera_vez=false;
}
else
{
posicTilde_rasgo1=posicTilde_rasgo2;
posicTilde_rasgo2=CalculaPosicionTilde(rasgos[j].palabra); /*Calculo la posición
C-46
Anexo C. Listado de programas
}
else if (argc==6)
{
strcpy(FicheroPruebas,argv[1]);
strcpy(FicheroBDEjemplos,argv[2]);
strcpy(FicheroPesos,argv[3]);
strcpy(FicheroEvaluacion,argv[4]);
strcpy(FicheroEstadisticasEvaluacion,argv[5]);
}
ejemplos=CargaEjemplos(DIRECTORIO, FicheroBDEjemplos);
if (ejemplos!=NULL)
{
TEjemplo EjemploPrueba; //Contiene el ejemplo que se va leyendo del fichero
de la tilde en rasgos (no en rasgos2, pues ahí se eliminó
la tilde*/
if (posicTilde_rasgo1!=posicTilde_rasgo2 || posicTilde_rasgo2!=posicTilde_ej)
{
acierto=false;
break;
}
}
}
}
}
delete [] pal_aux;
if (pal_encontrada==false)
{
acierto=false;
NumEjemplosCategNoEncont++;
}
return acierto;
}
/*Esta función calcula el número de palabras-categoría del fichero de rasgos*/
TIndiceEj CalculaNumPalabrasCateg(char *directorio, char *NomFichero)
{
TIndiceEj i;
TIndiceEj contador=1;
char *linea=new char [1000];
FILE *fichero=flhOpen(directorio,NomFichero,"rt");
if (fichero==NULL)
{
errorPrintf("falta el fichero %s",NomFichero);
}
for (i=0; feof(fichero)==0; i++)
{
if (i%1000==0)
printf("Llevo contados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero)!=NULL)
contador++;
else
break;
}
flhClose(fichero);
delete [] linea;
return contador;
}
void main(int argc,char *argv[])
{
if (argc==1)
{
de pruebas
TIndiceRasgos NumRasgosFichPruebas; //Nº de rasgos que lee del fichero de pruebas
char *linea=new char [1000];
TIndiceEj contOK=0;
TIndiceEj contTildesCatOK=0;
bool tildesOK=false;
bool acierto_cat=false;
TIndiceEj i;
int k;
ContPalabrasCateg=CalculaNumPalabrasCateg(DIRECTORIO, FicheroRasgos);
ContPalabrasCateg+=CalculaNumPalabrasCateg(DIRECTORIO, FicheroRasgosPrue);
rasgos = CargaRasgos(DIRECTORIO, FicheroRasgosPrue, FicheroRasgos);
rasgos2 = CargaRasgos2(DIRECTORIO, FicheroRasgosPrue, FicheroRasgos);
pesos = InicializaPesos(DIRECTORIO,FicheroPesos);
FILE *fichero1=flhOpen(DIRECTORIO, FicheroEvaluacion, "wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",FicheroEvaluacion);
}
k=fprintf(fichero1,"%s\n\n","Num_Rasgos Rasgo1 ... RasgoN Soluc_Leida
_Soluc_Estimada Frec_SolMasProb Dist_Min Pal_leida");
if (k==EOF)
errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion);
FILE *fichero2=flhOpen(DIRECTORIO, FicheroPruebas, "rt");
if (fichero2==NULL)
{
errorPrintf("falta el fichero %s",FicheroPruebas);
}
FILE *fichero3=flhOpen(DIRECTORIO, FicheroEstadisticasEvaluacion, "wt");
if (fichero1==NULL)
{
errorPrintf("falta el fichero %s",FicheroEstadisticasEvaluacion);
}
FILE *fichero4=flhOpen(DIRECTORIO, FicheroErroresTildado, "wt");
if (fichero1==NULL)
{
C-47
Anexo C. Listado de programas
errorPrintf("falta el fichero %s",FicheroErroresTildado);
}
for (i=0; feof(fichero2)==0; i++)
{
if (i%100==0)
printf("Llevo evaluados %ld ejemplos\n",(long)i);
if (fgets(linea,1000,fichero2)!=NULL)
{
TIndiceRasgos j;
char *token=linea;
token=strtok(token," ");
NumRasgosFichPruebas = atoi(token);
if (NumRasgos != NumRasgosFichPruebas)
{
errorPrintf("error de formato en el fichero de pruebas");
}
token = NULL;
for (j=0; j<NumRasgos; j++)
{
token=strtok(token," ");
if (token==NULL)
{
errorPrintf("error de formato en
l'inea %d",(long)i);
}
float aux=LeeFlotante(token,i);
EjemploPrueba.rasgos[j] = aux;
token=NULL;
}
token=strtok(NULL," ");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
EjemploPrueba.solucion = LeeSolucion(token,i);
token=strtok(NULL," ");
if (token==NULL)
errorPrintf("error de formato en l'inea
%d",(long)i);
EjemploPrueba.frecuencia = LeeFlotante(token,i);
token=strtok(NULL,"\n");
if (token==NULL)
{
errorPrintf("error de formato en l'inea
%d",(long)i);
}
strcpy(EjemploPrueba.comentario,token);
}
else
break;
}
SolucionEvaluada = DecisionSolucion(EjemploPrueba.rasgos);
k=fprintf(fichero1,"%d ", (int)NumRasgos);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
for (TIndiceRasgos j=0; j<NumRasgos; j++)
{
k=fprintf(fichero1,"%.0f ",
(float)EjemploPrueba.rasgos[j]);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
if (SolucionEvaluada == EjemploPrueba.solucion)
{
contOK++;
acierto_cat=true;
k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s\n",
(float)EjemploPrueba.solucion,
(float)SolucionEvaluada,
(float)frecSolucMasProbable, (float)distMin,
EjemploPrueba.comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
else
{
k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s_ERROR\n",
(float)EjemploPrueba.solucion,
(float)SolucionEvaluada,
(float)frecSolucMasProbable, (float)distMin,
EjemploPrueba.comentario);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEvaluacion);
}
tildesOK=EvaluaTildesCat(EjemploPrueba,SolucionEvaluada);
if (tildesOK==true)
{
contTildesCatOK++;
}
else
if (acierto_cat==true)
{
k=fprintf(fichero4,"%s\n",
EjemploPrueba.comentario);
if (k==EOF)
{
C-48
Anexo C. Listado de programas
errorPrintf("error en la escritura
del fichero %s",FicheroErroresTildado);
acierto_cat=false;
}
}
k=fprintf(fichero3,"%s\n", "Estad'sticas de la evaluaci'on:");
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisticasEvaluacion);
k=fprintf(fichero3," Tasa de aciertos en la resolución de ambiguedad en la
cat.(en%%): %f (%ld de %ld)\n",
(contOK/(float)i)*100,contOK,(long)i);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisticasEvaluacion);
k=fprintf(fichero3," Tasa de aciertos en la resolución del tildado(en%%): %f
(%ld de %ld)\n",
(contTildesCatOK/((float)i-(float)NumEjemplosCategNoEncont))*100,contTildesCatOK,((long)i(long)NumEjemplosCategNoEncont));
k=fprintf(fichero3," Número de palabras evaluadas no encontradas como
rasgos: %ld\n",
NumEjemplosCategNoEncont);
if (k==EOF)
errorPrintf("error en la escritura del fichero
%s",FicheroEstadisticasEvaluacion);
flhClose(fichero1);
flhClose(fichero2);
flhClose(fichero3);
flhClose(fichero4);
delete [] linea;
delete [] pesos;
}
delete [] ejemplos;
delete [] rasgos;
delete [] rasgos2;
}
C-49
Documentos relacionados
Descargar