Metaphone para Português
Publicado por Perfil removido 19/12/2008
[ Hits: 8.497 ]
A implementação de português do Brasil para metaphone é muito importante para verificar a semelhança fonética de substantivos; próprios, comuns, abstratos e concretos.
Existem muitas maneiras de se explorar a análise textual com esta ferramenta simples. E ainda com o novo acordo ortográfico, ficou ainda mais fácil de se manter esta função para todos os países de língua portuguesa. O algoritmo foi desenvolvido em C, para codificação UTF-8.
Acredito que pessoas mais experientes possam tornar o script melhor e que pessoas menos experientes possam aprender alguma coisa.
/* ** @title Metaphone pt-BR ** @ctime 19/12/2008 ** @author Lucas Fernando Amorim <lf.amorim@yahoo.com.br> * * * gcc metaphone_ptBR.c -o metaphone_ptBR.o */ #include <string.h> #include <stdio.h> int main(int argc, char **argv) { /* Verifica se possui argumento*/ if(argc < 1) /* Sem argumentos não dá!*/ return -1; /* Valores para laços e limites */ int palavra,letra,percorrer_ate; /* Saidas legais. */ char * encontrar; char saida_nao_prevista_legal[] = {'D','R','T','F','J','K','L','X','V','B','N','M'}; /* Percorre argumentos */ for(palavra=1;palavra<argc;palavra++){ /* Solicita última posição do argumento */ percorrer_ate = strlen(argv[palavra])-1; /* Primeiro FOR para correção de acentos */ for(letra=0;letra <= percorrer_ate;letra++){ /* Verifica se é acento usando codificação UTF-8. */ if(argv[palavra][letra] == '\xc3'){ /* Caso seja, requere segundo byte UTF-8. */ letra++; /* Verifica acentos possíveis em português. */ switch(argv[palavra][letra]){ /* Através do segundo valor hexadecimal executa a conversão para A */ case '\x80': case '\x81': case '\x82': case '\x83': case '\xa0': case '\xa1': case '\xa2': case '\xa3': argv[palavra][letra] = 'A'; break; /* Através do segundo valor hexadecimal executa a conversão para E */ case '\x88': case '\x89': case '\x8a': case '\xa8': case '\xa9': case '\xaa': argv[palavra][letra] = 'E'; break; /* Através do segundo valor hexadecimal executa a conversão para I */ case '\x8c': case '\x8d': case '\x8e': case '\xac': case '\xad': case '\xae': argv[palavra][letra] = 'I'; break; /* Através do segundo valor hexadecimal executa a conversão para O */ case '\x92': case '\x93': case '\x94': case '\x95': case '\xb2': case '\xb3': case '\xb4': case '\xb5': argv[palavra][letra] = 'O'; break; /* Através do segundo valor hexadecimal executa a conversão para U */ case '\x99': case '\x9a': case '\x9b': case '\x9c': case '\xb9': case '\xba': case '\xbb': case '\xbc': argv[palavra][letra] = 'U'; break; /* Através do segundo valor hexadecimal converte executa a convesão para Ç */ case '\xa7': argv[palavra][letra] = '\x87'; break; } /* Se não for caracter de controle, vamos tornar maiúsculo */ } else /* Caso não seja um acento faz a conversão para maísculas. */ argv[palavra][letra] = toupper(argv[palavra][letra]); } /* Laço fonético */ for(letra=0;letra <= percorrer_ate;letra++){ switch(argv[palavra][letra]){ /* A E I O U Y H são descartados. */ case 'A': case 'E': case 'I': case 'O': case 'U': case 'Y': case 'H': break; /* As seguintes regras para C */ case 'C': /* Se hover algo na frente */ if(letra <= percorrer_ate){ /* Se for H volta X */ if(argv[palavra][letra+1] == 'H') printf("X"); /* Se for E ou I volta S */ else if(argv[palavra][letra+1] == 'E' | argv[palavra][letra+1] == 'I') printf("S"); /* Se for A,O ou U volta K */ else if(argv[palavra][letra+1] == 'A' | argv[palavra][letra+1] == 'O' | argv[palavra][letra+1] == 'U') printf("K"); } /* Do contrário removemos o C. */ break; /* As seguintes regras para G */ case 'G': /*Se tiver um E na frente vira J*/ if(letra <= percorrer_ate & argv[palavra][letra+1] == 'E') printf("J"); /* Do contrário continua G */ else printf("G"); break; /* As seguintes regras para P */ case 'P': /* Se letra adjacente for H, vira F. */ if(letra <= percorrer_ate & argv[palavra][letra+1] == 'H') printf("F"); /* Do contrário continua P */ else printf("P"); break; /* As seguintes regras para Q */ case 'Q': if(letra <= percorrer_ate & argv[palavra][letra+1] == 'U') printf("K"); else /* Do contrário continua Q */ printf("Q"); break; /* Se for S executar a seguinte regra. */ case 'S': /* Se não estiver no final e for cercado por vogais, tem som de Z*/ if(letra <= percorrer_ate & letra > 0 & ( argv[palavra][letra+1] == 'A' | argv[palavra][letra+1] == 'E' | argv[palavra][letra+1] == 'I' | argv[palavra][letra+1] == 'O' | argv[palavra][letra+1] == 'U' ) & ( argv[palavra][letra-1] == 'A' | argv[palavra][letra-1] == 'E' | argv[palavra][letra-1] == 'I' | argv[palavra][letra-1] == 'O' | argv[palavra][letra-1] == 'U' )) { printf("Z"); break; } /* Se tiver um S na frente, não retornada nada. */ else if(letra <= percorrer_ate & argv[palavra][letra+1] == 'S') ; /* Se tiver um H na frente, retorna X. */ else if(letra <= percorrer_ate & argv[palavra][letra+1] == 'H') printf("X"); /* Do contrário continua S.*/ else printf("S"); break; /* Se for Z executar a seguinte regra. */ case 'Z': /* Se for a última posição, retorna S */ if(letra == percorrer_ate) printf("S"); /* Do contrário retorna Z */ else printf("Z"); break; /* Se for Ç converter para S. */ case '\xc3': letra++; if(argv[palavra][letra] == '\x87') printf("S"); break; /* W é convertido para V */ case 'W': printf("V"); break; /* Regra Default */ default: /* Verifica se é um caractere válido, isso dispensa inclusive \xc3 */ encontrar = memchr(saida_nao_prevista_legal,argv[palavra][letra],strlen(saida_nao_prevista_legal)); if(encontrar != NULL) printf("%c",argv[palavra][letra]); } } } /* Quebrar linha ao sair e dizer que foi tudo bem. */ printf("\n"); return 0; }
Lista duplamente encadeada com cabecalho
Desenhando uma superfície Bézier
Métodos de Ordenação - Quick Sort
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Desempenho abaixo do esperado - travadas e congelamento do sistema ope... (6)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta