paulo1205
(usa Ubuntu)
Enviado em 16/11/2021 - 10:30h
ApprenticeX escreveu:
Boa Noite a Todos!
Eu montei o algoritmo abaixo pra remover acentos e passar tudo para minúsculas, que acredito que uso no meu dia a dia!
Gostaria de saber se meu algoritimo está bom, ou se é possível fazer melhor!
Então quem tiver alguma idéia, ou crítica, gostaria de saber!
Uma coisa que eu noto é que você fez os testes de todas as letras candidatas à remoção de acentos mesmo depois de possivelmente já saber qual a letra (por exemplo: supondo que você já trocou
L'Á' por
L'a' , você continua entrando nos cinco
if s seguintes e, pela forma como eles foram construídos, compara a letra já trocada com cada uma das letras acentuadas equivalentes a
e ,
i ,
o ,
u e
c . Assim sendo, uma primeira correção seria trocar aquele conjuntos de
if por uma tripa
if /
else if /
else if /
… /
else .
if(/* testes da letra a*/)
text[ch]=L'a';
else if(/* testes da letra e */)
text[ch]=L'e';
else if(/* testes da letra i */)
text[ch]=L'i';
else if(/* testes da letra o */)
text[ch]=L'o';
else if(/* testes da letra u */)
text[ch]=L'u';
else if(/* testes da letra c */)
text[ch]=L'c';
Mas melhor ainda do que o encadeamento usando
else seria trocar por
switch , pois muitos compiladores implementam esses testes de forma muito mais eficiente, com uma tabela de desvios indexada pelo valor sendo examinado, em lugar de testar cada valor individualmente e em sequência.
switch(text[ch]){
case L'A':
case L'À':
case L'Á':
case L'Â':
case L'Ã':
case L'à':
case L'á':
case L'â':
case L'ã':
text[ch]=L'a';
break;
case L'C':
case L'Ç':
case L'ç':
text[ch]=L'c';
break;
/*
… etc.
*/
}
Lembrando que uso acentos!
Esse algoritimo é para meu aprendizado pessoal, logo, não é um trabalho que tenha regras, e nem pra uso profissional que também seguirá padrões!
Apenas trata-se de pequenos algoritmos cujo qual eu quero controlar e dominar completamente, motivo que nestes casos, não quero usar funções prontas porque elas não me ensinam nada!
Usei wchar porque ele trabalha com acentos, diferente do char que me forçaria a verificar 2 caracteres por vez, porém, ainda assim, vou depois montar o mesmo algoritimo com o simples char porque acho que eu apreciaria mais, ficando mais simples e ocupando menos Bytes, visto que o wchar está gastando 4 Bytes contra 1 Byte do char.
Cuidado que o nome do tipo é
wchar_t , não “wchar”.
#include <locale.h>
#include <wchar.h>
int main(void) {
setlocale(LC_ALL, "");
wchar_t Text[] = L"áéíóú àèìòù âêô ãõ ç ABCaÇÁ";
for(int Ch = 0; Text[Ch] != '\0'; ++Ch) {
if(Text[Ch] >= 'A' && Text[Ch] <= 'Z') Text[Ch] = Text[Ch] + 32;
else Text[Ch] = Text[Ch];
if(Text[Ch] == L'Á' || Text[Ch] == L'À' || Text[Ch] == L'Â' || Text[Ch] == L'Ã' || Text[Ch] == L'á' || Text[Ch] == L'à' || Text[Ch] == L'â' || Text[Ch] == L'ã') Text[Ch] = L'a';
if(Text[Ch] == L'É' || Text[Ch] == L'È' || Text[Ch] == L'Ê' || Text[Ch] == L'é' || Text[Ch] == L'è' || Text[Ch] == L'ê') Text[Ch] = L'e';
if(Text[Ch] == L'Í' || Text[Ch] == L'Ì' || Text[Ch] == L'í' || Text[Ch] == L'ì') Text[Ch] = L'i';
if(Text[Ch] == L'Ó' || Text[Ch] == L'Ò' || Text[Ch] == L'Ô' || Text[Ch] == L'Õ' || Text[Ch] == L'ó' || Text[Ch] == L'ò' || Text[Ch] == L'ô' || Text[Ch] == L'õ') Text[Ch] = L'o';
if(Text[Ch] == L'Ú' || Text[Ch] == L'Ù' || Text[Ch] == L'ú' || Text[Ch] == L'ù') Text[Ch] = L'u';
if(Text[Ch] == L'ç' || Text[Ch] == L'Ç') Text[Ch] = L'c';
}
wprintf(L"%ls\n", Text);
}
A solução mais genérica seria usar algoritmos padronizados de alguma biblioteca de internacionalização (como a ICU, por exemplo) para decomposição de caracteres com marcas diacríticas em caráter-base mais caráter diacrítico combinante (por exemplo: tomando como entrada o caráter “ã” (U+00E3), a decomposição resultaria em “a” (U+0061) mais o til combinante (U+0303, que é diferente do til individual, em U+007E)). Aí você descartaria a marca diacrítica combinante, retendo apenas o caráter-base.
... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)