// Copyright (c) 2008 Pedro Quaresma, Coimbra, Portugal // Versão 1.0 // Cálculo do Índice de Coincidência~\cite{Stinson2006} %{ #include /* Codificação: (a,97)-(z,122); (à,-32)-(ã,-29); (ç,-25)-(ê,-22); (ì,-20)-(î,-18); (ó,-13)-(õ,-11); (ù,-7)-(ú,-6); (ü,-4); os índices do vector vão coincidir com os valores da codificação dos caracteres, que no caso dos caracteres acentuados é ajustada de forma a não haver conflitos, 122+1+64 = 187, 122 - valor numérico de "z" (o maior positivo) +1 - a próxima posição +32 - o valor (mais negativo) de "à" isto dado não se poderem considerar índices negativos. O gasto de memória que esta solução implica não é (muito) significativo. A solução tem de passar por adoptar os novos tipos de "wide chars" ou algo do género. */ #define MAXCOD 155 %} int i; double conta_palavra=0; int conta_letra=0; int vec[MAXCOD]; char ch; double frequenciaRelativa; double d1; double d2; letras [a-z]|"á"|"à"|"ã"|"â"|"ç"|"é"|"è"|"ê"|"í"|"ì"|"ó"|"ò"|"õ"|"ô"|"ú"|"ù"|"ü" %% {letras} { if(yytext[0]<0) { // 122+1-4=119 ('z'+1-'ü'), isto para obter uma gama contínua i =-1*yytext[0]+119; vec[i]++; conta_letra++; } else { i = yytext[0]; vec[i]++; conta_letra++; } } .|\n %% main(int argc, char *argv[]) { // interface linha de comando // media char *ficheiroEntrada,*ficheiroSaida; double somaFis=0,total_letras=0,indiceCoincidencia; FILE *fsai, *fopen(); if (argc<=2) { // valores de entrada insuficientes (2+1) printf("\nUtilização: indiceCoincidencia nome_ficheiro_entrada nome_ficheiro_saída\n\n"); return; } // obtêm os argumentos da linha de comando ficheiroEntrada=argv[1]; ficheiroSaida=argv[2]; //printf ("\nFicheiro a Processar: %s\nFicheiro com resultados: %s\n\n",ficheiroEntrada,ficheiroSaida); if ((yyin = fopen(ficheiroEntrada,"r")) == NULL) { printf("Não foi possível abrir o ficheiro %s\n",ficheiroEntrada); } else if ((fsai = fopen(ficheiroSaida,"w")) == NULL) { printf("Não foi possível abrir para escrita o ficheiro %s\n",ficheiroSaida); } else { // processar yylex(); // Contar o número total de letras for (i=0; i < MAXCOD; i++) if(vec[i] != 0) { total_letras = total_letras+vec[i]; } for (i=0; i < MAXCOD; i++) { if(vec[i] != 0) { // printf("vec[%d]=%c,%d,%f\n",i,i,vec[i],total_letras); if (i>124) { ch=-1*(i-123); d1=vec[i]; somaFis=somaFis+d1*(d1-1); } else { ch=i; d1=vec[i]; somaFis=somaFis+d1*(d1-1); } } } // escreve o índice de coincidência indiceCoincidencia = somaFis/(total_letras*(total_letras-1)); fprintf(fsai,"%0.6f\n",indiceCoincidencia); } }