Idiomas de Programação
Fernando López Ostenenero e Ana García Serrano
O concurso conhecido “Figuras e letras” propõem dois tipos de testes para seus participantes: um dos números em que eles devem ser abordados tanto quanto possível para uma composições básicas do número alvo em vários números e um teste de letras, onde devem encontrar Lapalábra ( Válido) mais tempo que é possível escrever com uma série de letras.
Nesta prática, criaremos um programa que resolva o segundo desses testes. O programa receberá uma série de letras e retornará Todas as palavras válidas construam com eles. Para verificar se uma palavra é válida ou não, é essencial usar um dicionário.
Para fazer isso, um arquivo será fornecido com o dicionário de dicionário 79517 para o dicionário do rae para que os alunos possam Teste seu programa. Problemas de paraving devido à codificação de caracteres, todas as palavras foram excluídas e os acentos gráficos foram removidos.
Assim, a prática será dividida em duas fases diferentes:
- Criação do dicionário: um arquivo de texto que contém as palavras que vamos considerar válido (uma palavra por linha) será inserida e cada uma delas será inserida em uma estrutura de dicionário em que as palavras possíveis serão consultadas.
- Pesquisar por palavras: Uma vez disponível o dicionário, o programa fará o usuário a sequência de letras analisar e retornar todas as palavras válidas possíveis que podem ser construídas a partir dessas letras, encomendadas em ordem alfabética e agrupada por tamanho As coisas as coisas que a entrada / saída no paradigma funcional não faz parte da agenda que é estudada o assunto, todas as funções responsáveis por ler o dicionário de um arquivo ou l Assuntos com o usuário será agendado para os alunos. Nesta declaração, haverá explicação do funcionamento das referidas funções.
Declaração de prática
A prática é elaborar um programa em Haskell que carrega um arquivo de texto válido do Conspalabra e acredita em um dicionário . Assim que isso é feito, o programa solicitará ao usuário para sequências de letras diferentes e retornará as palavras válidas (aquelas presentes no eldicionário) que podem ser construídas com base nas letras disponíveis.
Exemplo 1: O programa procura Arquivo de dicionário por palavras (dicionário.txt), constrói o dicionário e espera que o usuário insira uma seqüência de letras:
* principal > Lista de palavras maincargo do Dicionário file.txt79517 Palavras de leitura
insira seqüência de letras:
Exemplo 2: Com o dicionário já carregado acima, o usuário insere a sequência de letras “aosc” e o programa retorna todos os Palavras do dicionário que pode ser construído usando letras:
Aqui podemos ver o dicionário resultante representado graficamente em um formulário de árvore. Como anteriormente sedegated, os nós intermediários (exceto a raiz, representados como RN) Único quem sabe personagens. E a concatenação dos caracteres que formam o caminho do acessível raiz dos nós de folha (representados como wn) indica as palavras presentes no eldicionário.
Para uma melhor compreensão da estrutura de dados a serem usadas, nós Sugerir estudantes que executam um horário em turnê no dicionário mostrado na Figura 1 para verificar exatamente as onze palavras indicadas na lista que foi usada para criá-la.
2.2 Estrutura de módulos de prática
A prática é dividida em dois módulos, cada um em um arquivo independente cujo nome (incluindo maiúsculas e minúsculas) com o nome do módulo e cuja extensão é .hs:
- dicionário do módulo: dentro deste Módulo, as funções de construção e acesso ao dicionário serão agendados. Ele também inclui a definição do tipo de dados do dicionário.
- módulo principal: Este módulo contém o programa principal e todas as funções responsáveis pelo carregamento da lista de palavras e interagindo com o usuário.
Como um estudo mais profundo dos módulos em Haskell está fora do escopo da Laassignature, apenas indicaremos que cada módulo importa uma série de módulos necessários para sua operação. Em nossa prática, as principais importações do módulo (além do módulo do módulo) módulos adicionais para poder trabalhar com a saída, arquivos e converter todas as letras Aminissus. Além disso, a lista de identificadores entre parênteses que acompanha o ano do módulo do dicionário representa as definições de tipos e funções que o ModuleExport.Qualquer outra definição será considerada privada, sendo apenas acessível pelo módulo.
Figura 1: Dicionário representado na árvore em forma
2.3 Tipo de dados do dicionário (módulo de dicionário)
Nesta seção, vamos apresentar o tipo de dados que vamos usar para armazenar em prática. É definido na parte do módulo de dicionário que fornece ensino eleger. Como vimos na seção anterior, um dicionário será uma árvore na qual os nós intermediários conterão um personagem, enquanto os nós de folha nos darão a formação de que palavras pertencem ao dicionário. Assim, a definição do dicionário Tipo:
dicionário de dados = RootNode | LetterNode char | WordNode
ou seja, um dicionário é um rootnode (nó raiz) que contém uma lista de dicionários , UnletterNode (letra do nó) que contém um caractere e uma lista de dicionários, um wordnode (nó de palavra) que será um nó da folha que nos marca que a concatenação de todas as características dos nós da raiz (que não Não contém nenhum) até o pai do nó da folha, uma palavra válida do dicionário.
Este tipo de dados é adicionado como instância da classe Show, para poder visualizar o conteúdo de um tipo de dicionário elemento e, assim, facilitar a tarefa de programar as funções de decrees do dicionário.
A representação interna do dicionário da Figura 1 seria a seguinte:
rootnode]]], LetterNode ‘C’ C ‘ ], LetterNode ‘S’, LetterNode ‘C’], Letterde ‘O’]]], Letternde’o ‘]]], Letterde’ O ‘]]]], Letterde’ S ‘] ], LetterNode ‘O’]]]]]
Qual é um pouco mais complicado de ler do que sua representação gráfica.
2.4 Programa principal (módulo principal)
O módulo principal contém o programa principal, já programado pela equipe de ensino. Feno que usam monads e são escritos usando a “notação de fazer”, que é uma notação para facilitar a redação de concatenações de funções monórgicas. Sem entrar demais. Assuma o funcionamento das Mônadas, explicaremos os tipos de dados definidos e que cada função.
Tipos de dados
- wordsn: representa uma lista de palavras. Nós usaremos esse tipo para se referir a uma lista de todos os mesmos comprimentos e organizada alfabeticamente .
- palavras: representa uma lista de palavras. Vamos usar este tipo para se referir a uma lista de palavras agrupadas em listas de palavras de igual comprimento e organizadas alfabeticamente.
Função de inserção
Seu tipo seria inserção :: string – > dicionário – > dicionário. Esta função é a um inserindo uma palavra no dicionário, mas já pensava como uma árvore. O primeiroparâmetro deve ser O resto da palavra que continua a ser inserido e o segundo parâmetro a árvore nodododel de que outro descanso de palavra deve ser inserido.
InsertChild Função
do tipo InsertChild :: char – > – > – >. No primeiroParameter recebe o primeiro caractere do resto da palavra a ser inserido, o segundo parâmetro o restante da palavra a ser inserido (sem o primeiro caractere), o terceiro parâmetro uma lista de elementos de entopete (que será o filhos de um nó). Retorna a lista de filhos do nó corretamente alterado.
Esta função é responsável por procurar a criança do nó atual, onde a inserção dos caracteres ainda permanece na palavra atual continua. No caso de a criança não existir, a função de Lodeber criará. Uma vez localizado (ou criado) a criança certa, a função deve continuar o restante dos caracteres da palavra dessa criança. Neste ponto, sugerimos que os alunoscriados “à mão” o dicionário representava na Figura 1 para uma melhor compreensão do processo inserindo palavras no dicionário.
2.6 consultas para o dicionário (módulo de dicionário)
Nesta seção, tentaremos as consultas para o dicionário. Nosso objetivo será programar pesquisar a sequência que recebe uma sequência de personagens e um dicionário. É devolvido pela lista Scucriry, ordenada alfabeticamente, que estão contidas em O dicionário e que podem ser convertidos com os caracteres de sequência.
busca :: string – > dicionário – >
Por exemplo, se procurarmos a sequência “cascao” no dicionário representado na Figura 1, devemos obter a seguinte lista de palavras:
Observe que “casos” e ” Pôr do sol “, presente no dicionário, não podem ser formados com as letras do Feijão, uma vez que contém apenas um ‘s’ (e” casos “tem dois) e Um ‘O’ (e “Sundo” tem dois).
Como vamos tomar a busca?Vamos supor que já fizemos uma rota anterior, nos levou a um nó da árvore (que não é uma folha). Portanto, teremos um sequenciamento de caracteres ainda não utilizados e o início de uma palavra formada pelos caracteres apresentamos o caminho da raiz para o nó atual.
Agora, analisamos todas as crianças do nó atual:
- Se uma criança é um wordnode, isso significará que a palavra que já formamos pertence ao dicionário, com o qual, será necessário adicioná-lo.
- Se uma criança é uma letternade, ela conterá um personagem. Somente se este personagem pertence à sequência ainda não explorada (em qualquer posição, não necessariamente o primeiro), devemos recussivamente explorar esta criança, adicionando à palavra já formou o caractere do lettertode e eliminando o dito caractere da sequência ainda não explorada .
Nós recomendamos novamente que os alunos investem um tempo na execução deste esfoliante na árvore da figura 1 para a sequência “Cascao” e verifique tão exatamente as palavras indicadas.
Como na seção anterior, a função de pesquisa precisará de uma série de funções (que não será visível a partir do exterior do módulo). Os mais importantes são os seguintes LASSDOS:
Função SearchIntree
Seu tipo seria SearchIntree :: string – > string – > dicionário – >
Você deve retornar todas as palavras contidas no dicionário cujo início é o conteúdo por Descobrindo o parâmetro e continue a partir do nó atual (terceiro parâmetro) usando apenas soletários de seqüência ainda não explorados (primeiro parâmetro).
Função SearchChild
SearchChild :: string – > string – > dicionário – >. A função recebe a sequência ainda não explorada, o início da palavra já construída (com base na rota empregada para atingir este nó da raiz) e um nó (filho do nó atualmente sendo explorado). Esta é a função que ser aplicado o algoritmo explicado acima para retornar a lista escarrária que pode ser formada com o começo já construído, e com os caracteres que ainda não são usados.
problemas na prática
a resposta a essas perguntas é opcional. No entanto, se o aluno não responder a essas questões, a qualificação da prática só pode atingir 6 pontos em 10.
- (1’5 pontos). Suponha uma implementação de prática em uma linguagem não declarativa (como Java, Pascal, C …). Comente quais vantagens e que desvantagens eu teria em frente à implementação em Haskell. Relaxe estas vantagens do ponto de vista da eficiência em relação à programação e execução. Qual seria o ponto principal em favor da implementação em línguas não declarativas? E a implementação em Haskell?
- (1’5 pontos). Indique, com suas palavras, o que permite gerenciar o predicado não lógico predefinido, corte (!), Em proll. Como esse efeito seria realizado em Java? Justifique sua resposta.
- (1 ponto). Para os tipos de problemas do problema definido em Haskell (em ambos os módulos), indique quais tipos de construtores de tipo foram usados em cada caso (veja o capítulo 5 do livro do assunto).
Documentação para entregar
Cada aluno deve entregar a seguinte documentação ao seu tutor prático: – código-fonte no Haskell que resolve o problema posado. Para fazer isso, os arquivos lyrics.hs e dicionário.hs devem ser entregues, com as funções descritas nesta instrução, bem como todas as funções auxiliares necessárias. – Uma memória com: – uma pequena descrição das funções agendadas. – as respostas a questões na prática.