Metaphone para Português
Publicado por Perfil removido 19/12/2008
[ Hits: 8.860 ]
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;
}
Desenhando uma curva Dragão ou o Fractal Jurassic Park
Desenhando uma superfície Bézier
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Atualizar Linux Mint 22.2 para 22.3 beta
Jogar games da Battle.net no Linux com Faugus Launcher
Como fazer a Instalação de aplicativos para acesso remoto ao Linux
Conky, alerta de temperatura alta (9)
Assisti Avatar 3: Fogo e Cinzas (3)
Duas Pasta Pessoal Aparecendo no Ubuntu 24.04.3 LTS (42)









