Está en la página 1de 12

MAC2301Laboratorio de Programacao

Aula 01
Professores: Joao Eduardo Ferreira e Marcelo Finger
Primeiro Semestre de 2012

O que s
ao algoritmos?
Descric
ao de um procedimento formal que recebe um conjunto
de valores de entrada e produz um conjunto de valores de sada.
(Cormen et al.)
Para resolver um problema:
Abstrac
ao da realidade do problema (quais os dados que interessam?).
Representac
ao dos dados, depende tambem das operacoes que vao ser
realizadas sobre eles.

Exemplo 1 (Wirth) Representac


ao dos n
umeros:
tracos (adic
ao f
acil)
ar
abicos (adic
ao mais complicada, mas outras
operac
oes mais simples)
bin
arios (adequado para computador, mas n
ao para n
os)
Representac
ao escolhida depende das informaco
es a serem guardadas e
da forma como ser
ao manipuladas.

Revis
ao r
apida de C

Problema 1 Dado um n
umero natural n, imprimir todos os n
umeros primos entre 2 e n.
1

2.1

Soluc
ao 1

Contador i varia de 2 a n. Para cada valor, testa se i e primo, se for,


imprime. Para testar se i e primo, verifica se algum n
umero entre 2 e i 1
e um divisor de i.
2.1.1

#i n c l u d e <s t d i o . h>
i n t main ( ) {
int
i , j , / C o n t r o l e de l a c o .
/
n,
/ L i m i t e s u p e r i o r .
/
primo ; / primo v a l e 1 s e o numero e primo /
/ e 0 c . c .
/
p r i n t f ( D i g i t e o v a l o r de n : ) ;
s c a n f (%d,&n ) ;
f o r ( i = 2 ; i <= n ; i ++){
primo = 1 ;
f o r ( j = 2 ; j < i ; j ++)
/ s e i tem um d i v i s o r nao e primo
i f ( i%j == 0 ) primo = 0 ;
i f ( primo == 1 ) p r i n t f (%d , i ) ;
}
p r i n t f (\n ) ;

return 0;
}
2.1.2

C++

Primeiras diferencas entre C e C++: cin, cout, namespace


2.1.3

cin, cout

A linguagem C++ possui uma biblioteca de classes relacionadas ao controle de entrada e sada de dados. Em particular, a classe cout e utilizada

para exibir valores enquanto que a classe cin e utilizada para armazenar
valores recebidos por meio do teclado em variaveis. Na linguagem C as
func
oes printf e scanf eram utilizadas para executar essas mesmas funcoes.
Entretanto, observe que a denominacao apropriada que usamos para essas
funcionalidades na linguagem C++ foi classe e nao funcao!
As sintaxes utilizadas para cin e cout sao respectivamente:

cin >> variavel_destino;


cout << <valor, string, vari
avel, ponteiro, etc>;

O operador << indica ao comando cout que um dado deve ser exibido
na tela, alem de identificar automaticamente qual o tipo desse dado e como
ele deve ser formatado para exibicao na tela.
2.1.4

Namespace

Um namespace e uma regi


ao declarativa que atribui um identificador adicional a quaisquer nomes declarados dentro dessa regiao. O identificador
adicional torna menos prov
avel que um nome possa entrar em conflito com
nomes declarados em outras partes do programa. Sendo assim, mesmo sendo
sin
onimos, os nomes que estao em namespaces separados serao u
nicos por
causa da adic
ao do identificador de namespace. Exemplo:

namespace Palmeiras {
char func(char);
class String { ... };
}
// alguma biblioteca corintia.h
namespace corintia {
class String { ... };
}

Dessa maneira, os nomes das classes nao irao conflitar, pois eles sao
referenciados respectivamente como: Palmeiras::String e corintia::String.

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
i n t main ( ) {
int
i , j , / C o n t r o l e de l a c o .
/
n,
/ L i m i t e s u p e r i o r .
/
primo ; / primo v a l e 1 s e o numero e primo /
/ e 0 c . c .
/
c o u t << D i g i t e o v a l o r de n : ;
c i n >> n ;
f o r ( i = 2 ; i <= n ; i ++){
primo = 1 ;
f o r ( j = 2 ; j < i ; j ++)
/ s e i tem um d i v i s o r nao e primo
i f ( i%j == 0 ) primo = 0 ;
i f ( primo == 1 ) c o u t << i << ;
}
c o u t << e n d l ;

return 0;
}

2.2

Soluc
ao 2

Crivo de Erat
ostenes: Vetor contendo os n
umeros de 2 a n. Contador inicia
no 2. Testa os seguintes e os que forem m
ultiplos, transforma em 0.
2.2.1

#d e f i n e TAM 1000
i n t main ( ) {
int
v e t [TAM] , / Vetor que r e p r e s e n t a o c r i v o . /
i, j,
/ Contadores de l a c o .
/

n;

/ L i m i t e s u p e r i o r .

p r i n t f ( D i g i t e o v a l o r de n : ) ;
s c a n f (%d , &n ) ;
/ I n i c i a l i z a c a o do c r i v o
f o r ( i = 2 ; i <= n ; i ++) v e t [ i ] = 1 ;
i = 2;
w h i l e ( i i <= n ) {
/ Marca o s m u l t i p l o s de i .
f o r ( j = i +1; j <= n ; j ++)
i f ( v e t [ j ] != 0 && j%i == 0 )
vet [ j ] = 0;

/ Pula nao primos a t e proximo primo .


/
f o r ( j = i +1; v e t [ j ] == 0 && j <= n ; j ++);
i = j;
}
/ I m p r e s s a o dos primos . /
f o r ( i = 2 ; i <= n ; i ++)
i f ( v e t [ i ] != 0 ) p r i n t f (%d , i ) ;
p r i n t f (\n ) ;
return 0;
}
2.2.2

C++

#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
#d e f i n e TAM 1000
i n t main ( ) {
int
v e t [TAM] , / Vetor que r e p r e s e n t a o c r i v o . /
i, j,
/ Contadores de l a c o .
/

n;

/ L i m i t e s u p e r i o r .

c o u t << D i g i t e o v a l o r de n : ;
c i n >> n ;
/ I n i c i a l i z a c a o do c r i v o
f o r ( i = 2 ; i <= n ; i ++) v e t [ i ] = 1 ;
i = 2;
w h i l e ( i i <= n ) {
/ Marca o s m u l t i p l o s de i .
f o r ( j = i +1; j <= n ; j ++)
i f ( v e t [ j ] != 0 && j%i == 0 )
vet [ j ] = 0;

/ Pula nao primos a t e proximo primo .


/
f o r ( j = i +1; v e t [ j ] == 0 && j <= n ; j ++);
i = j;
}
/ I m p r e s s a o dos primos . /
f o r ( i = 2 ; i <= n ; i ++)
i f ( v e t [ i ] != 0 ) c o u t << i << ;
c o u t << e n d l ;
return 0;
}
Obs: Pode-se melhorar bastante o crivo alterando-se o laco que olha os
seguintes para:
/ E li m in a m u l t i p l o s . /
f o r ( j = i i ; j <= n ; j += i ) v e t [ j ] = 0 ;

2.3

Soluc
ao 3

Vetor contendo 1 nas posic


oes de 2 a n. Elimina m
ultiplos. Vantagem: vetor
n
ao precisa ser do tipo int. Veja uma implementacao usando um vetor de
bits em http://paca.ime.usp.br/file.php/385/crivo_bits.c

Recurs
ao
1. Fatorial: Definic
ao matematica:
0! = 1
n! = n (n 1)!
Algoritmo recursivo:
int fat ( int n) {
i f ( n == 0 )
return 1;
else
r e t u r n n f a t ( n 1);
}
2. Fibonacci: Definic
ao matematica:
F (0) = 0
F (1) = 1
F (n) = F (n 1) + F (n 2)
Algoritmo recursivo:
i n t Fib ( i n t n ) {
i f ( n == 0 )
return 0;
e l s e i f ( n == 1 )
return 1;
else
r e t u r n Fib ( n1)+Fib ( n 2);
}

Veja mais sobre recurs


ao em: http://www.ime.usp.br/~pf/algoritmos/
aulas/recu.htm

Ordena
c
ao de um vetor

4.1

Selec
ao

A cada passo, selecionamos o menor elemento do vetor v[i..n1] e colocamos


na posic
ao i. Sabemos que o vetor v[0..i 1] esta em ordem crescente e
v[i 1] v[i..n 1].
Complexidade: O(n2 ).
void s e l e c a o ( i n t n , i n t v [ ] ) {
i n t i , j , min , aux ;
f o r ( i = 0 ; i < n1; i ++) {
/ Procura o minimo no v e t o r de i a n1. /
min = i ;
f o r ( j = i +1; j < n ; j ++)
i f ( v [ j ] < v [ min ] ) min = j ;
/ Coloca o minimo no i n i c i o . /
aux = v [ i ] ;
v [ i ] = v [ min ] ;
v [ min ] = aux ;
}
}
Vers
ao recursiva:
void s e l e c a o r e c ( i n t i , i n t n , i n t v [ ] ) {
i n t j , min , aux , x ;
i f ( i <n1) {
/ Procura o minimo de no v e t o r de i a n1. /
min = i ;
f o r ( j = i +1; j < n ; j ++)
i f ( v [ j ] < v [ min ] ) min = j ;
/ Coloca o minimo no i n i c i o . /
x = v[ i ];
v [ i ] = v [ min ] ;
v [ min ] = x ;

s e l e c a o r e c ( i +1,n , v ) ;
}
}

4.2

Inserc
ao

A cada passo, sabemos que o vetor v[0..i 1] esta em ordem crescente.


Guardamos o valor de v[i] em j. Percorremos o vetor de v[i 1] para
tr
as deslocando cada elemento uma casa para frente ate encontrarmos um
elemento menor que j. Inserimos o valor de j apos o u
ltimo elemento testado.
void i n s e r c a o ( i n t n , i n t v [ ] ) {
int j , i , x ;
f o r ( j = 1 ; j < n ; j ++) {
x = v[ j ];
/ Move o s e l e m e n t o s m a i o r e s que v [ j ] uma c a s a para f r e n t e . /
f o r ( i = j 1; i >= 0 && v [ i ] > x ; i )
v [ i +1] = v [ i ] ;
/ Coloca v [ j ] no e s p a c o que s o b r o u . /
v [ i +1] = x ;
}
}

4.3

Intercalac
ao (Mergesort)

Ideia: Divide na metade, ordena as duas metades e intercala.


Para intercalar as metades ordenadas, e preciso resolver o seguinte problema auxiliar: suponha que v[p..q1] e v[q..r1] estao em ordem crescente;
queremos colocar v[p..r 1] em ordem crescente.
Intercala: Entrada: vetor v, inteiros p, q, r, tais que
v[p..q 1] e v[q..r 1]
est
ao ordenados.
Sada: vetor v[p...r 1] ordenado.
i = p; j = q; k = p;

Enquanto n
ao acabou nenhuma metade:
se (v [ i ] < v [ j ] )
w[ k ] = v [ i ] ;
i = i +1;
sen
ao w[ k ] = v [ j ] ;
j = j +1;
k = k+1;
Copia o pedaco que sobrou de um vetor. Copia tudo de w em v.
Usando intercala, o algoritmo de ordenacao fica:
void mergesort ( i n t p , i n t r , i n t v [ ] ) {
int q ;
i f ( p < r 1) {
q = (p + r )/2;
mergesort (p , q , v ) ;
mergesort (q , r , v ) ;
i n t e r c a l a (p , q , r , v ) ;
}
}
Resolvemos log(n) problemas (dividindo por dois a cada vez), cada rodada leva tempo O(n), a complexidade e O(n log(n))
Exerccio 1 Comparar os tempos de execucao dos algoritmos de ordenacao
vistos em aula. Testar com vetores aleatorios e tambem com os seguintes
casos limite:
vetor j
a est
a ordenado,
vetor ordenado em ordem decrescente e
vetor com todos os elementos iguais.
Para testar o tempo use:
#i n c l u d e <time . h>
...
d o u b l e time1 , time2 , t o t a l ;

time1 = ( d o u b l e ) c l o c k ( ) ;
<Chamada da func
a o>
time2 = ( d o u b l e ) c l o c k ( ) ;
t o t a l = ( d o u b l e ) ( time2time1 ) /CLOCKS PER SEC ;
Para preencher um vetor com valores aleatoriosuse:
#i n c l u d e <s t d l i b . h>
void preenche ( i n t v [ ] , i n t n){
int i ;
srand ( 0 ) ;
f o r ( i = 0 ; i < n ; i ++)
v [ i ] = rand ()%MAX; / MAX deve s e r d e f i n i d o /
}
Bibliografia: Cormen et al. captulos 1 e 2.
Exerccio 2 ((Extra) Torre de Hanoi) Ha um jogo interessante cuja a
soluc
ao e naturalmente recursiva. Ele consiste de 3 varetas e alguns discos.
Uma das varetas contem uma pilha de n discos de modo que os raios diminuem da base para o topo. As outras duas estao vazias. O jogo consiste em
passar os discos da vareta original para uma das outras sempre movendo o
disco do topo e nunca colocando um disco de raio maior sobre um disco de
raio menor.
|
-------------

|
|
|
|
|

|
|
|
|
|

vareta 1

Ex. de configurac
ao original
Escreva um programa de computador que apresente quais movimentos
devem ser feitos. Por exemplo no caso acima com quatro discos a sada
deveria ser algo como:

Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova
Mova

o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

disco
disco
disco
disco
disco
disco
disco
disco
disco
disco
disco
disco
disco
disco
disco

do
do
do
do
do
do
do
do
do
do
do
do
do
do
do

topo
topo
topo
topo
topo
topo
topo
topo
topo
topo
topo
topo
topo
topo
topo

da
da
da
da
da
da
da
da
da
da
da
da
da
da
da

vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta

1
1
2
1
3
3
1
1
2
2
3
2
1
1
2

para
para
para
para
para
para
para
para
para
para
para
para
para
para
para

a
a
a
a
a
a
a
a
a
a
a
a
a
a
a

vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta
vareta

2
3
3
2
1
2
2
3
3
1
1
3
2
3
3

También podría gustarte