Verificador ortográfico

:!: Este projeto foi aprimorado e atualizado para o formato UTF-8.

Este projeto visa implementar um verificador ortográfico simples, que verifica se as palavras de um texto de entrada estão em um dicionário predefinido e sugere correções para as palavras não encontradas.

Descrição

O verificador de ortografia recebe um texto de entrada e verifica se suas palavras estão em um dicionário. A saída deve reproduzir fielmente o texto de entrada (inclusive espaços e quebras de linha), mas colocando entre colchetes as palavras não encontradas no dicionário.

Por exemplo, para esta entrada:

   Para que o pocessador possa interromper a execução de uma
tarefa e retornar a ela mais tarde, sem corromper seu estado
interno, é necessário definir operações para salvar e
restaurrar o contexto da tarefa.
===
   O ato de salvar os valores do contexto atual em seu TCB e
possivelmente restaurar o contexto de outra tarefa, previamente
salvo em outro TCB, é denominado "troca de contexto".

O programa deve gerar esta saída:

   Para que o [pocessador] possa interromper a execução de uma
tarefa e retornar a ela mais tarde, sem corromper seu estado
interno, é necessário definir operações para salvar e 
[restaurrar] o contexto da tarefa.
===
   O ato de salvar os valores do contexto atual em seu [TCB] e
possivelmente restaurar o contexto de outra tarefa, previamente
salvo em outro [TCB], é denominado "troca de contexto".

Consideram-se como palavras as sequências contíguas de letras (A-Z, a-z) com ou sem acentos e as cedilhas; os demais caracteres (números, espaços e outros símbolos) não fazem parte de palavras.

Exemplos de arquivos de texto com erros de ortografia, no formato UTF-8 (baixe com “salvar como”, para evitar conversões de caracteres indesejadas):

Os arquivos acima e o dicionário estão no formato UTF-8, que é o padrão da maioria dos sistemas atuais. Esse formato pode usar mais de um byte por caractere para representar letras acentuadas e sinais gráficos. Se for usar outros textos, assegure-se de que também estejam no formato UTF-8.

Sugestões

Um bom verificador ortográfico deve sugerir correções para as palavras incorretas. Programe o verificador para informar as palavras conhecidas mais próximas das palavras não encontradas no dicionário, como mostra este exemplo:

   Para que o [pocessador (processador)] possa interromper a execução de uma
tarefa e retornar a ela mais tarde, sem corromper seu estado
interno, é necessário definir operações para salvar e
[restaurrar (restaurar)] o contexto da tarefa.
===
   O ato de salvar os valores do contexto atual em seu [TCB (aba)] e
possivelmente restaurar o contexto de outra tarefa, previamente
salvo em outro [TCB (aba)], é denominado "troca de contexto".

Para encontrar a palavra mais próxima no dicionário, sugere-se usar a distância Levenshtein, que permite calcular a distância entre duas strings.

O algoritmo de Levenshtein é lento, portanto evite comparar palavras de comprimentos muito diferentes (por exemplo, evite calcular a distância entre “uva” e “laranja”).

Forma de chamada

$ ortografia [-s] [ -d dicionário ] [ -i entrada ] [ -o saída ]

Opções:

Essas opções podem ser usadas em qualquer ordem:

// entrada e saída em arquivos
ortografia -i input.txt  -o output.txt
ortografia -o output.txt -i input.txt

// entrada em arquivo, saída em stdout, vice-versa ou ambos
ortografia -i input.txt  > output.txt
ortografia -o output.txt < input.txt
ortografia <  input.txt  > output.txt

// as opções podem estar em qualquer ordem
ortografia -d brazilian -i input.txt -o output.txt
ortografia -i input.txt -d brazilian -o output.txt -s
ortografia -o output.txt -s -i input.txt -d brazilian

Atividade

A implementação deve atender os seguintes requisitos:

Para medir o tempo de execução do programa, use o comando time:

time ./ortografia -i brascubas.txt -o output.txt

Arquivos a entregar ao professor:

Dica: as funções da biblioteca C padrão (StdLib) podem facilitar a implementação de seu programa:

Consulte as páginas de manual para aprender a usar essas funções.

Sugestões de implementação

Por pseudocódigo:

ler o dicionário em um vetor de palavras

c = ler caractere da entrada

enquanto não for o fim da entrada faça
  
  // avançar até encontrar uma letra ou o fim da entrada 
  enquanto (c não for uma letra) e (não for o fim da entrada) faça
    escrever c em stdout
    c = ler caractere da entrada
  fim enquanto

  // encontrou uma letra, ler a palavra inteira
  palavra = ""
  enquanto (c for uma letra) e (não for o fim da entrada) faça
    palavra = palavra + c
    c = ler caractere da entrada
  fim enquanto

  // tratar a palavra encontrada 
  se palavra <> "" então
    se minúscula(palavra) está no dicionário então
      escrever palavra na saída
    senão
      escrever "[", palavra, "]" na saída
    fim se
  fim se

fim enquanto

Por máquina de estados:

state = 0
while state ≠ 2 do

   read input

   case (state)

      0: case (input)

            letter:
               append input to word
               state = 1

            not letter:
               print input

            eof:
               state = 2

         end case

      1: case (input)

            letter:
               append input to word

            not letter:
               check word
               print word
               reset word
               state = 0

            eof:
               check word
               print word
               state = 2

         end case

   end case
end while