Aula Prática 2 Previs˜ao, Ciclos e Somatórios Ordenaç˜ao e Dividir

Propaganda
DAA 2015/2016 (CC2001)
DCC/FCUP
Aula Prática 2
Previsão, Ciclos e Somatórios
Ordenação e Dividir para Conquistar
Para efeitos da nota atribuida à resolução de exercı́cios ao longo do semestre, os exercı́cios a submeter
desta aula são:
• [03] - Ordenando Números (peso 10%)
• [04] - Tabela Classificativa (peso 40%)
• [05] - Inversões (peso 50%)
Previsão de Tempo de Execução
1. Imagine que tem um programa P implementado, que recebe como input n números. Ao experimentar
executá-lo com testes aleatorizados, obteve os seguintes tempos de execução:
• Com n = 300 demorou 1.5 segundos
• Com n = 600 demorou 12.0 segundos
• Com n = 1200 demorou 1m36s
(a) Qual será a complexidade assintótica mais provável do programa P ? Justifique.
(b) Estime quanto tempo demoraria o programa para um caso com 5, 000 números.
Ciclos e Somatórios
2. Quais os valores exactos da variável contador no final dos seguintes pedaços de código quadráticos?
Escreva a sua resposta como uma função de n.
Se tiver dificuldades pode experimentar implementar os programas na sua linguagem de programação
favorita e verificar empiricamente qual o valor da variável para vários valores de n.
(a) contador ← 0
Para i ← 1 até n fazer
Para j ← i até n fazer
contador ← contador + 2
(b) contador ← 0
Para i ← 1 até n fazer
Para j ← i + 1 até n − 1 fazer
contador ← contador + 1
(c) contador ← 0
Para i ← 1 até n fazer
Para j ← 1 até 2 × i fazer
contador ← contador + 3
1
Usando a biblioteca da sua linguagem para ordenar
3. A ordenação é uma operação ”básica” essencial em muitos algoritimos. É 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):
• C: qsort da stdlib (ver entrada nas manpages)
• C++: sort da STL (ver entrada no cplusplus.com)
• Java: Arrays.sort (ver entrada da referência da API do Java)
(a) Na página da cadeira é disponibilizado um pequeno programa para ordenar 10 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.
(b) Faça as (poucas) modificações necessárias no programa anterior para submeter uma solução para
o problema [03] - Ordenando Números usando a biblioteca da sua linguagem. Se obtiver um
Presentation Error não se esqueça que não podem existir espaços a mais ou a menos no output.
Ordenação com um critério personalizado
4. 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.
(a) Na página da cadeira é disponibilizado um pequeno programa para ordenar nomes por ordem
alfabética do apelido e em caso de empate por ordem alfabética do primeiro nome (customsort.c,
customsort.cpp ou CustomSort.java). Tem também disponı́vel um ficheiro com 160 nomes para
poder testar o programa: (names.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. Para o fazer use a seguinte linha de comando,
que compila e, caso consiga compilar com sucesso, executa o programa com o input do ficheiro
names.txt, escrevendo para o ficheiro output.txt
(C) gcc -Wall -o customsort customsort.c && ./customsort < names.txt > output.txt
(C++) g++ -Wall -o customsort customsort.cpp && ./customsort < names.txt > output.txt
(Java) javac CustomSort.java && java CustomSort < names.txt > output.txt
Para poder verificar o output pode por exemplo usar o comando cat:
cat output.txt
(b) Submeta o problema [04] - Tabela Classificativa.
2
Contando Inversões
3. Leia o problema [05] - Inversões, disponı́vel na página de DAA.
(a) Vamos tentar fazer uma primeira solução com pesquisa exaustiva (aka ”força bruta”), testando
todos os pares de números. Supondo que já temos a leitura feita para o array v[]:
contador ← 0
Para i ← 0 até n − 1 fazer
Para j ← i + 1 até n − 1 fazer
Se v[i] > v[j] então
contador ← contador + 1
escrever(contador)
Perceba o que faz o código acima descrito e implemente este programa em C/C++ ou Java.
Usando a notação dada, qual é a complexidade assintótica do algoritmo usado? Submeta o
programa no Mooshak e verifique que o último testes não passa por causa do tempo limite.
(b) Vamos tentar melhorar esta solução para Θ(n log n). Para isso vamos adaptar o MergeSort e
criar uma solução usando o paradigma ”Dividir para Conquistar” que ao mesmo tempo que vai
ordenando vai contando as inversões.
Na página da cadeira é disponibilizada uma implementação exmeplo do MergeSort:(mergesort.c,
mergesort.cpp ou MergeSort.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. Depois de o
fazer poder até submeter novamente o problema [03] - Ordenando Números com este código.
(c) Como adaptar o código anterior para contar inversões? A função mergesort(int v[], int
start, int end) deve passar a devolver um inteiro: o número de inversões. Para calcular com
divisão e conquista, o número de inversões total deverão ser a soma das inversões somente da
parte esquerda, das inversões somente da parte direita... e das inversões entre pares de partições
diferentes! O esqueleto da sua função deverá ser algo como:
contador = 0;
contador += mergesort(v, start, middle);
contador += mergesort(v, middle+1, end);
contador += merge(v, start, middle, end);
return contador;
Os dois primeiros incrementos estão já feitos (assumindo que a função funciona). A única coisa
que lhe falta fazer é calcular o número de inversões entre as duas partições (ordenadas). Consegue
imaginar como fazer? Pense um pouco por si antes de pedir ajuda, ou usar o Google :)
Submeta uma solução Θ(n log n) para o problema [05] - Inversões
3
Download