Escolar Documentos
Profissional Documentos
Cultura Documentos
Primeira Lista
Observações Iniciais
Esta disciplina é lecionada em linguagem C. Para todos os exemplos de código,
assuma que os devidos headers já estão inclusos. A lista segue a ordem dos conteúdos
dados em sala de aula.
Índice
inx = *parr++;
a) O código compila?
Escreva o conteúdo da função exibir, sabendo que ela deve percorrer o array de
nomes e printar um a um. Não há restrições para a formatação de exibição. Faça isso:
1.3) [Nomes de Arrays] Cite um contexto em que o nome de um array não é usado
como equivalente ao endereço deste array.
1.4) [Typedefs] Escreva os typedefs para os seguintes tipos:
d) PROC_t: uma função que retorna BOOL_t e recebe um único argumento que
é do tipo pointero para OBJECT_t.
1.5) [Malloc] Crie a função malloc_list que receba um int x e aloque espaço na
memória para um array de x elementos do tipo char*. Use um loop for para inicializar
todos os elementos como NULL. A função deve retornar um ponteiro para o espaço
alocado (equivalente a um ponteiro para o primeiro elemento).
temp = &count;
*temp = 20;
temp = ∑
*temp = count;
printf("count = %d, *temp = %d, sum = %d\n", count, *temp, sum);
a) f(n) = Ο(f(n)²)
2.3) [Limite Assintótico Superior] Suponha que cada expressão abaixo represente o
tempo T(n) consumido por um algoritmo para resolver um problema de tamanho n.
Escreva os termo(s) dominante(s) para valores muito grandes de n e especifique o
menor limite assintótico superior Ο(n) possível para cada algoritmo.
3.2) [Análise de Algoritmo] Analise o algoritmo abaixo, escrito em C, que recebe dois
arrays, a e b, de tamanhos iguais n. Determine:
int f(int n) {
int i, j, k, sum = 0;
for ( i=1; i < n; i *= 2 ) {
for ( j = n; j > 0; j /= 2 ) {
for ( k = j; k < n; k += 2 ) {
sum += (i + j * k );
}
}
}
}
1.1) a) Sim.
b) 10.
c) O ponteiro parr estará apontando para fora do array.
1.2) a)
b)
1.4) a)
b)
c)
d)
e)
1.5)
1.6)
2.1) a) É verdade. Para que 2n+1 pertença a Ο(2n), é preciso achar uma constante c tal
que, para algum valor de m, a seguinte desigualdade seja verdadeira:
b) Falso. Para que 22n pertença a Ο(2n), é preciso achar uma constante c tal que,
para algum valor de m, a seguinte desigualdade seja verdadeira:
Uma vez que 22n equivale a 2n.2n, sempre haverá um valor de n maior do que
qualquer constante c que possamos escolher. Assim, 2n não é um limite assintótico
superior para 22n.
Exemplo verdadeiro:
f(n) = 2n +3 e O(f(n)) = n
Então 3n+3 = θ(n) = θ(f(n))
Exemplo falso:
f(n) = 2n + 3 e O(f(n)) = n²
Então n²+2n+3 = θ(n²) ≠ θ(f(n))
d) Sempre falsa.
e) Sempre falsa.
1 = c.1000.log 1 0 1000
1 = 3000.c
c = 1/3000
T(n) = 1 .106.log10106
Para exercitar, tente recalcular a questão anterior usando essa nova expressão.
4.1) a) É possível perceber que, para cada recursão, o algoritmo executa um laço de
complexidade constante (o loop for executa aproximadamente 8 iterações em
qualquer circunstância) e realiza sua chamada recursiva de tamanho 3n/4. Assim,
chegamos na seguinte relação de recursividade:
T(n) = T(3n/4) + c
c + T (3n/4) =
c + c + T ((3/4)2n) =
c + c + c + T ((3/4)3n) =
c + c + . . . + c + T (1) =
c+c+...+c+c=
c.log4/3n ∈ θ(logn)
T(n) = T(n-5) + cn 3
cn3 + T(n−5) =
cn3 + c(n−5)3 + T(n−10) =
cn3 + c(n−5)3 + c(n−10)3 + c(n−15)3 + ... + T(1) =
cn3 + c(n−5)3 + c(n−10)3 + c(n−15)3 + ... + c
cn3 + T(n−5) =
cn3 + c(n−5)3 + T(n−10)
A chamada T(n/2) resultará em c(n/2)3 + T((n/2)-5). Visto que um termo somado a algo
positivo é necessariamente maior do que ele mesmo, temos uma desigualdade
bastante ingênua:
c(n/2) 3 + T((n/2)-5) ≥ c(n/2) 3
Apesar de óbvia, esta desigualdade nos permitirá gerar uma nova desigualdade, dessa
vez com relação à expressão do tempo de execução:
T(n) ∈ O(n 4 )
T(n) ∈ ω(n 4 )
Logo, T(n) ∈ θ(n 4 )
T(n) = 2*T(n/4) + cn
T(n) ∈ θ(f(n)) =
θ(n)
cn + 2 T(n/4) =
cn + 2 ( c.(n/4) + 2 T(n/42) ) => cn + cn(2/4) + 22.T(n/42) =
cn + cn(2/4) + cn(2/4)2 + cn(2/4)3 + ... + 2kT(n/4k) =
cn + cn(2/4) + cn(2/4)2 + cn(2/4)3 + ... + 2log4(n)c =
cn + cn(2/4) + cn(2/4)2 + cn(2/4)3 + ... + (2/4)log4(n)cn =
cn( 1 + (1/2) + (1/2)2 + ... + (1/2)log4(n) ) ≈
cn(2) = 2cn =
c’.n ∈ θ(n)
d) A recursividade encontra-se dentro de um loop for de 4 iterações e,
portanto, é chamada quatro vezes por execução, cada uma dividindo o problema pela
metade. O trabalho desenvolvido fora da recursão encontra-se principalmente dentro
dos dois loops for mais internos, de complexidade θ(n) cada. Como esses dois loops
estão entrelaçados, temos uma complexidade total de θ(n2). Isto nos leva à seguinte
relação de recursividade:
T(n) = 4 T(n/2) + cn 2
cn2 + 4 T(n/2) =
cn2 + 4( c.(n/2)2 + 4 T(n/22) ) => cn2 + cn2 + 42.T(n/22)) =
cn2 + cn2 + 42(c.(n/22)2 + 4 T(n/23)) => cn2 + cn2 + cn2 + 43.T(n/23) =
cn2 + cn2 + cn2 + ... + cn2 + 4log2(n).T(1) =
cn2 + cn2 + cn2 + ... + cn2 + cn2
CORMEN, Thomas H.; LEISERSON, Charles E.; RIVEST, Ronald L.; STEIN, Clifford.
Algoritmos: Teoria e Prática. Tradução de: Introduction to Algorithms, 3rd ed.
Rio de Janeiro: Elsevier, 2012.
Data Structures and Algorithms, The Ohio State University. Disponível em:
<http://web.cse.ohio-state.edu/~lrademac/Fa14_2331/RecursiveAnalysis.pdf>.
Acessado em: 06/05/2016.
Algorithms and Data Structures, The University of Auckland. Disponível em:
<https://www.cs.auckland.ac.nz/courses/compsci220s1t/lectures/lecturenotes/
GG-lectures/220exercises1.pdf>. Acessado em: 06/05/2016.
Lista de Exercícios do ex-monitor Felipe. Disponível em:
<http://www.del.ufrj.br/~heraldo/eel470_lista1.pdf>. Acessado em:
06/05/2016.