DAA 2021/2022 (CC2001) - DCC/FCUP

Aula Prática #03 - Ordenação e Pesquisa Binária
(semana de 21/03 a 25/03)


Exercícios para submissão

Para efeitos da nota atribuída à resolução de exercícios ao longo do semestre, os exercícios a submeter desta aula são:

Prazo de submissão: 10 de Abril (submeter no Mooshak de DAA)

Não se esqueçam que qualquer ajuda que tenham recebido de outros colegas deve ser reconhecida nos comentário do programa que submetem.
Depois do prazo os problemas continuarão disponíveis no Mooshak, mas as submissões não contarão para a sua nota. Relembre que cada aula vale 10% da nota desta componente.
Para um problema contar tem acertar todos os testes. Mesmo que resolva todos os problemas, o máximo numa aula é de 100%.


Conteúdos das teóricas

Nesta aula iremos abordar conceitos de ordenação e pesquisa binária. Será por isso conveniente ver o que foi falado nas teóricas:


Exercício 1) Usando a biblioteca da sua linguagem para ordenar

A ordenação é uma operação "básica" essencial em muitos algoritmos. É por isso comum que uma qualquer linguagem de programação tenha disponível na sua bilbioteca padrão uma função de ordenação, O objectivo deste exercício é levá-lo a conhecer como ordenar usando o sort disponível na sua linguagem preferida.

Iremos usar as seguintes funções (escolha a da linguagem que pretende usar):

  1. Tem ao seu dispor um pequeno programa que mostra como ordenar números inteiros: sort.c, sort.cpp ou Sort.java. Descarregue o código da sua linguagem de eleição e experimente compilar e executar na sua máquina, garantindo que percebe o programa.
  2. A mesma função de ordenação pode ser usada para quaisquer outros tipo primitivos. Experimente mudar o programa para outro tipo primitivo (ex: double ou char) e execute para verificar que a ordenação continua a funcionar.

Exercício 2) Ordenação com um critério personalizado

Por vezes queremos ordenar por um critério diferente do padrão (ex: por ordem decrescente; ordenar primeiro por um campo e depois por outro). Nesses casos queremos poder usar o sort da biblioteca, mas passar-lhe um comparador "customizado" que permita ordenar segundo o critério que desejamos.

  1. Tem ao seu dispor um pequeno programa para ordenar pessoas por ordem crescente da idade e em caso de empate por ordem alfabética do nome: customsort.c, customsort.cpp ou CustomSort.java. Tem também disponível um ficheiro com um exemplo de input para poder testar o programa: persons.txt. Descarregue o código da sua linguagem de eleição e experimente compilar e executar na sua máquina, garantindo que percebe o programa.
  2. O que precisaria de alterar no programa para ordenar por ordem decrescente da idade (ao invés da ordem crescente)? Experimente mudar, compilar e executar para testar o que pensou.

  3. Usando o que aprendeu, leia, resolva e submeta o problema [DAA 009] ADN Alienígena .


Exercício 3) Um problema com pesquisa binária "clássica"


Comece por ler o enunciado do problema [DAA 010] Somas mais próximas. O objectivo final deste exercício é conseguir submeter com sucesso uma solução. Em vez de considerar que são possíveis spoilers, neste problema queremos mesmo que siga os passos que sugerimos.

  1. Vamos começar por calcular todos as somas possíveis de pares de números. Se temos n números guardados num array v[], queremos todos os pares v[i] + v[j] com 0 ≤ i, j ≤ n-1.
    1. Exactamente quantos pares existem? (use o seu conhecimento sobre somatórios e progressões aritméticas obtido no capítulo anterior de matéria). Qual a sua ordem de grandeza em termos assintóticos?
    2. Implemente dois ciclos para guardar estes pares num novo array somas[] e confirme que a quantidade de pares é a que calculou..
  2. Para cada uma das Q perguntas vamos querer agora pesquisar no array pares[] procurando a(s) soma(s) mais próxima(s).
    1. Uma alternativa seria fazer uma simples pesquisa linear (um ciclo percorrendo todos os elementos de pares). Será que isto passaria no tempo necessário? Porquê?
    2. O array de somas é igual para todas as perguntas pelo que podemos pré-processar para depois melhorar a pesquisa. Sendo assim, podemos precisamente... ordená-lo! Use a biblioteca padrão da sua linguagem para ordenar o array.
    3. Depois de ter ordenado, podemos aplicar... pesquisa binária! É no entanto necessário cuidado porque o número que procuramos pode não estar no array. O que queremos realmente é o número mais próximo do que procuramos. Que versão da pesquisa binária dada nas aulas teóricas será mais útil para esta tarefa? [ver slides 23 a 26]
  3. No final, o esquema geral do algoritmo para este problema é o seguinte:

Exercício 4) Um problema com pesquisa binária "indirecta" (binary search the answer)


Implemente e submeta uma solução para o problema [DAA 011] Viagem de mochila às costas.

Use o algoritmo explicado nas aulas teóricas: [ver slides 27 a 36] e vídeo #09 - Ordenação: Pesquisa Binária Indirecta.


Exercício de Desafio

Todas as semanas vou colocar disponível pelo menos mais um exercício um pouco mais desafiante.

Para esta semana o desafio é diferente do habitual, sendo um problema de output-only, pelo que pode resolvê-lo usando uma qualquer linguagem de programação (ou até fazendo manualmente). O problema está disponível para submissão no Mooshak:

Se já tiverem feito tudo e estiverem "presos" neste, e quiserem mesmo fazer o desafio, podem contactar-me para eu "dosear" as dicas, sabendo que este problema é substancialmente mais difícil os outros desta aula.

Depois de terem submetido não deixem de falar comigo no Slack para explicarem as vossas ideias, uma vez que não vou ter acesso ao código que usaram para gerar a resposta :)