SANDRA PUGA
•
GERSON RISSE I li
www. pre n h a
ll.co m/ pu ga_br
Sandra Puga ,
o
·
Gerson Rissetti
•
I Ca
com aplicações em Java
PEARSON Prentice Hali
São Paulo Brasil Espanha
Argentina
Guatemala
Colômbia México
Costa Rica
Peru
Chile
Porto Rico
Venezuela
© 2004
by Sandra Puga e Gerson Rissetti
Todos os direitos reservados. Nenhuma parte desta publicação poderá ser reproduzida ou transmitida de qualquer modo ou por qualquer outro meio, eletrônico ou mecânico, incluindo fotocópia, gravação ou qualquer outro tipo de sistema de armazenamento e transmissão de informação, sem prévia autorização, por escrito, da Pearson Education do BrasiI. Diretor editorial: José Martins Braga Editor: Roger Trimer Editora de texto: Patrícia C. Rodrigues Preparação: Maurício Kibe Revisão: Thelma G uimarães e juliana Takahashi Capa: Marcelo Françozo Projeto gráfico e diagramação: Figurativa Arte e Proj eto Editorial
Dados Internacionais de Catalogação na Publicação (CIP) (Câmara Brasileira do livro, SP, Brasil)
Puga, Sandra Lógica de programação e estruturas de dados, com aplicações em Java I Sandra Puga, Gerson Rissetti. --São Paulo : Prentice Hall, 2003.
ISBN 85-87918-82-6 1. Dados - Estruturas (Ciência da computação) 2. Java (Linguagem de programação para computador).
3. Lógica I. Rissetti, Gerson. 11. Título.
03-5239
CDD-005.1 '
lndices para catálogo sistemático:
·1. Lógica estruturada : Computadores :
Processamento de dados
005.1
2004
Direitos exclusivos para a língua portuguesa cedidos à Pearson Education do Brasil, uma empresa do grupo Pearson Education Av. Ermano Marchetti, 1435, Lapa CEP: 05038-001, São Paulo- SP, Brasil Tel.: (11) 3613-1222. Fax: (11) 3611-0444 e-ma iI:
[email protected]
AGRAD E CI M E NTO E SPECIAL Agradecemos aos professores e amigos Marcos Alberto Bussab e Robert Joseph Didio pela grande colaboração na tarefa de revisar e criticar o nosso livro. SGP e GR
,.
DED ICATORIA E AGRADECI M E NTOS Dedico este trabalho ao Pedro, pois este pequeno personagem foi quem me deu motivação para organizar e produzir este material. Agradeço à Antonia por ter cuidado de mim e do Pedro durante as longas horas de trabalho. SGP
/
SUMARIO
-
APRESENTAÇAO .
. . .
.
. . .
.
. . .
.
. . .
.
..
. .
. .
.
. . . .
.
.
. . .
. .
..
. . . . . . . . . .
-
..
. .
.
XI
. . .
INTRODUÇAO ......................................................... XIII ,.
CAPITULO 1
-
'
,.
INTRODUÇAO A LOGICA .... . . .. . ....... .. .
.
.
0 USO DO RACIOCÍNIO LÓGICO NO DIA-A-DIA
1
0 USO DA LOGICA APLICADA A INFORMATICA
1
.
,
2
3
'
1
... ...... ... .. ..... .
.
.
.
.... ......... .. . .......... .... 2
1.1 .
. .
.
,
.
.
.
.
..
.
.
. . .
.
.
.
.
......
.
. .
.
.
.
.
. . .
.
.
.
.
. . .
.
.
2
EXERCÍCIOS PARA FIXACÃO ............................................................. 4 �
,
EXERCICIOS COMPLEMENTARES ...................................................... 5
1 .4 ,.
CAPITULO 2
-
INTRODUÇAO AOS ALGORITMOS . ....... .............. ... ..... 8 .
.
2. 1
2.3
.
,
PSEUDOCODIGO .
2.3. 1
2.6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
....
.
.
.
..
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
�
,
.
.
DECLARAÇAO DE VARIAVEIS CORPO DO ALGORITMO . . .
FLUXOGRAMA
2 .4. 1
.
.
.
.
.
.
IDENTIFICAÇÃO DO ALGORITMO
2.3.3
2.5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
TIPOS DE ALGORITMOS .. ........ ....... .... . . ...... . ...... ... ...
2.3.2
2.4
.
ALGORITMOS APLICADOS À SOLUÇÃO DE PROBLEMAS COMPUTACIONAIS
2.2
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.. .
.
.
.
.
.
.
.
.. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.. .
.
.
..
.
.
.
.
.
.
.
.
.
.
......
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
....
. . .
.
.
.
.
.
.
.
.
.
.
9 9
10
. 10 .
............... ... .... ...... .............. 11 .
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
... .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.. .
.
.
.
.
.
.
.
.
.
.
.
.. .
.
.
.
.
.
. .
.
.
.
.
.
.
... .
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
12
12
SIMBOLOGIA .......................... ....................... ................ 12 .
,
.
.
.
-
EXERCICIOS PARA FIXAÇAO ........................................................... 1 4 EXERCÍCIOS COMPLEMENTARES
..
. .. .
.
.
.
.
..
.
.
.
.
....
..
.
.
.
...
..
.
.
.
.
...
.
.
.
.
.
...
.
.
.
.
.
. 15
.
'
VIII
-
LOGICA DE PROGRAMAÇAO E ESTRUTURAS DE DADOS ,
CAPITULO 3 ,
CONCEITOS BASICOS SOBRE ALGORITMOS 3. I
TIPOS DE DADOS 3. I 1
.
.
. . .
.
.
.
.
. . . .
'
.
.
.
.
. . .
.
TIPOS CONSTRUIDOS .
.
'
3.2
.
VARIAVEIS
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . .
..
.
..
.
.
.
.
.
. . . . . .
.
...
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . .
. . . . . .
.
.
.
.
..
.
.
. . .
.
.
.
.
.
. . . . . .
.
.
.
.
.
. .
.
..
.
.
16
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
'
-
3.2.1
IDENTIFICAÇAO DAS VARIAVEIS PARA OS ALGORITMOS
3.2.2
IDENTIFICADORES DE VARIÁVEIS PARA A LINGUAGEM JAVA
3.3
CONSTANTES ..
3.4
OPERADORES .
.
.
.
.
.
.
.
.
.
.
.
.
.
..
. . . . . . . . . . . . . . .
.
.
. . .
. . . .
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
. .
.
.
.
.
.
.
. . . .
.
.
..
.
. . . . . . . . . . . . . . . . . . . . . . . .
.
..
.
.
.
.
.
.
.
.
.
.
.
.
... . . .
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
. . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
-
3.4.1
OPERADORES DE ATRIBUIÇAO
3.4.2
OPERADORES ARITMETICOS
3.4.3
OPERADORES RELACIONAIS
3.4.4
OPERADORES LOGICOS
3.4.5
PRECEDENCIA DOS OPERADORES
.
...
. .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
'
. . .
.
.
. . . . .
'
...
.
..
.
.
.
.
.
TABELA-VERDADE
3.6
EXERCÍCIOS PARA FIXAÇAO
3.7
EXERCÍCIOS COMPLEMENTARES
.
.
.
. .
.
.
.
.
. .
.
.
.
.
.
.
. . .
.
.
.
.. .
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
. . . . . .
.
. . . . . . . . . . . . . . . . . . . . . . .
A
3.5
.
.
.
.
.
.
.
. . .
.
.
.
.
. .
.
.
.
.
.
.
.
.
. .
. . . . . . . . .
. . .
.
.
.
. .
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o
o
.
o o .
.
.
.
.
. .
..
. .
. . . . . .
.
.
.
.
.
.
.
.
.
.
. . . .
• • o • • • • • • o
o
. o
. . . . .
.
.
-
.
.
.
.
.
.
. . . . . . . . . . . . . . . . • . . . . . . . . • .
o
• • o o
. . . . . . . . . . . . . . . . . . .
17 19 19 20
20 21 21 21 22 23 23 23 25 26 27
,
CAPITULO 4 29
-
CONCEITOS DE PROGRAMAÇAO '
-
4. I
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
-
INTRODUÇAO A PROGRAMAÇAO
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . • . • . . . . . . . . . . . . . . . .
-
4.2
TIPOS DE PROGRAMAÇAO
4.3
• • • o • o · · · · · ·
.
.
.
• • o • • • o • • · .
.
.
o o o • • . . . . . . . . . . . .
o o • · · · · · ·
4.2.1
CONCEITOS SOBRE A PROGRAMAÇÃO LINEAR
4.2.2
CONCEITOS SOBRE A PROGRAMAÇÃO ESTRUTURADA
. . .
.
.
.
.
.
. . . . .
.
. . . . . . .
.
.
.
.
.
.
.
'
0 QUE E UM OBJETO
4.3.2
COMO VISUALIZAR UM OBJETO? ...
4.3.3
CONCEITO DE CLASSES
4.3.4
INSTÂNCIAS DE OBJETOS
4.3.5
HERANÇA
4.3.6
POLIMORFISMO ...
4.3.7
ENCAPSULAMENTO
4.3.8
APLICAÇAO
·
·
·
·
.
.
.
.
. . . . . . . . . .
CONCEITOS SOBRE A PROGRAMAÇÃO ORIENTADA A OBJETOS 4.3.1
.
.
. . . .
. . . . . . . . . . . • . . . . . . . . . . . . • . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
·
·
·
·
·
. . .
o · · · · · · · · · .
. . . . . . . . .
..
. .
. .
. . . .
.
.
.
.
o
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
...
. . . .
. .
. . .
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
. . . . . . . . . .
.
.
.
.
.
. .
.
.
o
. . . . . . . . . . .
· · · · · · · · · · · · · · o · · · · · · · o · · · · · · · · · · · · · · o · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
. .
.
.
.
.
.
.
.
o • • o • • •
o
o
...
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . .
• • • o
o
o .
.
.
.
. .
.
.
.
...
.
.
.
.
.
.
.
o
.
0
•
•
•
o
•
• o o • · · ·
.
.
.
.
.
.
.
.
.
• • • • • • • • • • o • • • • • • • o . o
o
.
o
0
0
.
o
.
.
.
.
• • • • • o • • • • • • o • • • • •
o
o
.
.
.
.
.
.
o • o • • • • o
.
• • • • o
. . . . . . . .
.
.
.
-
'
. . .
o
.
o
o
o
-
4. 4
EXERCICIOS PARA FIXAÇAO
4.5
EXERCÍCIOS COMPLEMENTARES
. . . . . . . . . . . . . . . . .
.
.
.
.
. . .
.
. . . . . . . . . . . . . . .
.
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . • . . . . . . . . . . . . . . . . . . . . .
.
.
.
. . . . . . . . . . . . . .
30 32 32 32 34 36 37 .37 38 39 39 39 41 45 45
,
CAPITULO 5 CONSTRUÇÃO DE ALGORITMOS: ESTRUTURAS DE CONTROLE S. 1
ENTRADA
o
o
o
• • •· · · · ·
.
.
.
0 0 0 ·· · · · · • • • o o o • • • · • · · · · ·
.
.
0 0 0
.
.
•
•
.
•
.
.
• • •
.
.
• • •
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
46
oo•••••••···········••o• o••••••••·· 47
'
IX
SUMARIO '
SAlDA
5.2
.
.
.
.
.
.
.
.
.
.
.
... . .
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
�
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.5.3
ESTRUTURAS DE SELEÇAO OU DECISAO
5.4
ESTRUTURAS DE SELEÇÃO SIMPLES
5.5
ESTRUTURAS DE SELEÇÃO COMPOSTAS
5.6
ESTRUTURAS DE SELEÇÃO ENCADEADAS
5.7
ESTRUTURAS DE SELEÇÃO DE MÚLTIPLA ESCOLHA
5.8
ESTRUTURAS DE REPETIÇÃO
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . • . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . .
.
. . .
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . • . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
'
-
5.8. 1
. . 48
· · · · · · · · · · · · · · · · · · · · · · · ·
-
53 54 56 58 62 66
ESTRUTURA DE REPETIÇAO COM TESTE NO INICIOESTRUTURA ENQUANTO
5.8.2
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
66
ESTRUTURA DE REPETIÇÃO COM TESTE NO FIMESTRUTURA REPITA
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
'
-
5.8.3
69
ESTRUTURA DE REPETIÇAO COM VARIAVEL DE CONTROLE- ESTRUTURA PARA
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
-
5.9
EXERCÍCIOS PARA FIXAÇAO
5 . 1o
EXERCÍCIOS SUGERIDOS
5 .1 1
EXERCICIOS COMPLEMENTARES
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . • . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
'
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
72 74 75 76
"
CAPITULO 6 ESTRUTURA DE DADOS: VETORES 6.1
.
.
.
.
ESTRUTURAS INDEXADAS - VETOR (ARRAY)
6.2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
78
.
. . .
-
6.1. 1
DECLARAÇAO DE VETOR
6.1 .2
ACESSO E ATRIBUIÇÃO DE VALOR EM VETORES
6. 1.3
OPERAÇÕES
. . .
.
.
.
CONCEITO DE MATRIZES 6.2. 1
DECLARAÇÃO
6.2.2
OPERAÇOES
.
.
. . . .
.
.
.
.
.
.
.
.
.. ...... .
.
.
.
.
.
.
.
.
.
.
.
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
... .. ... .
.
.
.
.
.
.
.
. . .
.
. .
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
......
.
.
.
.
.
.
.
.
. . . .
.
.
..
.
. .
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . .
.
.
.
.
.
...
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . .
.
.
. .
. . .. .
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
...
.
. .
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . • . . . -
EXERCÍCIOS PARA FIXAÇAO
6.4
EXERCICIOS COMPLEMENTARES
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
'
. . . .
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
86 95
.. 96
-
6.3
79
. 81
. . .
.
.
79
96
102
. . 104 .
"
CAPITULO 7 1 05
-
PROCEDIMENTOS E FUNÇOES 7.1
PROCEDIMENTOS 7 .1.1
• • • • • • • •
•
.
.
.
.
.
.
.
.
• • • • • • • • • • • • • • • • • • • • • • •
•
CHAMADA DE PROCEDIMENTOS
.
.
.
.
o
o
o
o
o o
o
o
•
• o • • • • • • • • • • • • •
.
.
. . . . . .
.
.
.
.
.
.
.
.
. . . . .
.
o
o
.
o
o
o
.
o
o
o
o
.
•
• •
•
• • • • • • • • • • • • • • • • •
.
.
.
.
.
. .
.
.
.
.
. .
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
-
7.2
FUNÇOES
7.3
ESCOPO DE VARIAVEIS . .
7.4
PARAMETROS
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
'
.
.
. . . . .
.
.
.
.
. .
.
.
.
.
.
.
.
. . . . .
.
.
.
.
.
.
.
.
. . . . . . .
.
. . .
.
.
.
.
. . . .
.
.
.
... . .
.
.
.
. . . .
...
.
. . . . . . .
.
.
..
.
.
. . . .
.
.
.
.
. .
.
.
.
.
.
.
. . . .
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
PARAMETROS FORMAIS
7.4.2
PARAMETROS REAIS . .
7.4.3
PASSAGEM DE PARAMETROS
7.4.4
PASSAGEM DE PARAMETROS POR VALOR
7.4.5
PASSAGEM DE PARAMETROS POR REFERENCIA
.
•
. .
. . . .
.
. . .
.
. . . . .
.
.
.
. . .
..
. . . . . . .
.
. .
.
.
.
. . . . . .
..
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . .
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . . . . . . . .
. . . . . .
.
.
.
.
.
.
.
. . .
.
"
A
'
.
.
.
.
.
.
.
.
.
.
.
.
A
. . . . . . . . . . . . . . . . .
-
7.5
EXERCICIOS PARA FIXAÇAO
7.6
EXERCÍCIOS COMPLEMENTARES
.
.
.
.
.
.
.
.
.
..
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.... .
.
.
.
.
.
.
.
.
.
.
.
.
....
.
.
.
.
.
.
.
.
.
.
.
.
....
.
.
.
.
.
.
.
.
.
.
.
. . . . .
1 16
. 1 16
A
.
1 13
.
•
7 .4. 1
108
. ... 1 15
•
.
106
.
.
.
.
.
.
.
.
.
.
1 17 1 19 1 19 1 20 1 20 120
-
'
LOGICA DE PROGRAMAÇAO E ESTRUTURAS DE DADOS
X
,
CAPITULO 8 BUSCA E ORDENAÇÃO
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8. I
ORDENAÇAO POR TROCAS- METODO DA BOLHA
8.2
8USCA .
. . . . . . . .
.
. . . . . . . . .
.
.
.
.
..
.
.
.
.
.
.
..
.
.
.
.
.
.
.
.
. .
.
.
.
.
..
. .
.
.
.
.
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
BUSCA LINEAR (OU SEQÜENCIAL)
8.2.2
BUSCA BINÁRIA (OU BUSCA LOGARÍTMICA) .....
.
.
.
..
EXERCICIOS PARA FIXAÇAO
8.4
EXERCICIOS COMPLEMENTARES
.
.
.
.
.
. . . . . . . .
.
.
.
.
..
.
.. I 23 .
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
. . . . .
-
8.3
. .
1 22
.
. . . . . . . . . . . . . . . . .
8.2. I /
.
'
-
.
.
. . . . . . . . . . .
.
. . . . . . . . . . . . . . . .
.
. . .
. . .
. . .
131 131
. I 37
. . . . . . . . . . . . . . .
'
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
I 41 142
,
CAPITULO 9 ACESSO A ARQUIVOS
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1 43
.
'
9. I
. .............................................................. 144 O QUE E UM ARQUIVO?
9.2
ARQUIVO-TEXTO
9.3
TIPOS DE ARQUIVO QUANTO AS FORMAS DE ACESSO
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
. . .
. . . . . .
.
.
'
9.3.1
ARQUIVOS SEQÜENCIAIS
9.3.2
ARQUIVOS DE ACESSO ALEATORIO
.
.
.
. . . . . . . . . . . .
.
.
OPERAÇÕES DE MANIPULAÇÃO DE ARQUIVOS
9.4
-
SEQUENCIAIS 9.4.2
. . . . . . . . . . . . . . . . . . . . . . . . . .
.
. . . . . . . . .
.
.
.
.
.
.
.
.
. . . . .
. . . . . . . .
. . . . . . .
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
. .
. .
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
'
-
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. .
.
.
.
.
9.5
EXERCICIOS PARA FIXAÇAO
9.6
EXERCICIOS COMPLEMENTARES
.
.
.
.
.
'
.
.
.
. . .
.
.
. . . . . . . . . . . . .
10
.
..
..
.
. .
.
.
LISTAS
.
.
.
.
.
. . .
.
.
.
.
.
.
.
. .
.
.
.
.
..
.
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
I 45 145 146 146
146
LISTAS ENCADEADAS .
10. 1.2
TIPOS DE LISTAS ENCADEADAS
.
.
.
.
10.2
LISTAS DE ENCADEAMENTO SIMPLES ...
10.3
LISTAS DUPLAMENTE ENCADEADAS
10.4
FILAS
10.5
PILHAS
10.6
ARVORES
.
.
.
.
.
.
.
.
.
.
..
.
.
.
.
.
.
.
.
. .
.
.
.
.
.
.
. .
.
.
.
.
.
. . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . .
.
.
.
. .
. . . .
.
.
...
.
..
. . .
. . . . . . . . .
..
.
. . . . . . . . . . . . .
10.6. 1
'
. . . . .
. .
'
.
.
.
.
.
.
.
. . . . . . . .
..
.
.
.
.
.
.
. . . . . . . . . . . .
.
.
.
.
.
.
.
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . .
'
ARVORES BINARIAS
.
. .
.
.
.
.
.
. . .
.
.
.
.
..
. .
.
. . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
..
.
.
.
.
.
.
.
.
. .
.
.
.
o
o . o o
o
. . . . . . . .
•
•
•
• • •
.
.
o
.
. . . . . o o o • • • • • • o o o o o o o o o • • • o o o o o • o • • o • o • . o o o o o o • • • o • • o o
-
EXERCICIOS PARA FIXAÇAO
.
.
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
I 80 I 81
183 184 186
. 187
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
'
I 65
182
.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . • . . . . . . . . .
10.1.1
. . . . . . . . .
.
. .
"
ESTRUTURAS DE DADOS DINAMICAS
10.7
. .
.
REPRESENTAÇÃO DA MANIPULAÇÃO DE ARQUIVOS '
10.1
.
.
-
DE ACESSO ALEATORIO
CAPITULO
. . .
1 44
REPRESENTAÇAO DA MANIPULAÇAO DE ARQUIVOS
9.4.1
,
..
. . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
'
.
.
.
. . .
201 205 213 220 221 233
ANEXO CONCEITOS SOBRE A LI NGUAGEM JAVA
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
,236
APRESENTAÇÃO
U
m livro que aliasse a lógica de programação, que é efetivamente praticada nos meios acadêmicos, com sua implementação na linguagem Java era um anseio de professores e alunos, e é a esse anseio que esta publicação vem atender. O livro aborda desde os princípios básicos de lógica até assuntos mais comple xos, mas igualmente necessários, numa linguagem que, sem perder o rigor científico necessário às obras desse porte, é compreensível pelos estudantes de diferentes graus de conhecimento e dificuldade. Os tópicos vão desfilando de maneira didática e tecnica mente adequada, tornando o aprendizado uma tarefa menos árdua. O texto é rico em exemplos e há uma série de exercícios práticos com diferentes graus de dificuldade. Esta obra é, acima de tudo, um reflexo da experiência profissional e acadêmica de seus autores e uma contribuição de suma impo11ância para a bibliografia nacional na área de computação e informática.
Prof. Marcos Alberto Bussab Coordenador da área de ciências da computação da Uninove
INTRODUÇÃO
L destinado a todas as pessoas interessadas em programação de computadores,
ógica de programação e estruturas de dados com. aplicações em Java é um livro
mas especialmente aos estudantes da área de computação, pois foram eles nossa grande fonte de inspiração - muitos dos exemplos e exercicios são frutos colhidos nas salas de aula. Procuramos sintetizar num único livro os assuntos que julgamos essenciais para contribuir para a formação de um bom programador: lógica de programação, estrutura de dados e aplicações em Java. Escolhemos a linguagem de programação Java para implementação dos algoritmos por dois motivos: a necessidade de profissionais espe cializados em Java e a necessidade de uma bibliografia básica que mostrasse passo a passo o uso de estruturas de seleção, repetição, ordenação, filas e pilhas, dentre outros, implementadas em Java. A linguagem de programação Java é fundamentalmente orientada a objetos, mas nosso objetivo não é estudar esse tipo de programação. Faremos uso de recursos bastan te simples, sem nos preocuparmos com questões mais sofisticadas da orientação a obje tos, que serão levemente abordadas no Capítulo 4. Os conceitos aqui abordados poderão ser adaptados às questões encontradas no dia-a-dia, inclusive com o uso de outras linguagens, uma vez que todos os exemplos são descritos em pseudocódigo e depois transcritos para Java.
XIV
- E ESTRUTURAS DE DADOS LOGICA DE PROGRAMAÇAO '
No Capítulo 1 são abordados algw1s conceitos da lógica como ciência pura, ain da sem a sua aplicação na computação. Sem grandes pretensões, queremos apenas mos trar que o uso da lógica faz parte de nosso cotidiano. No Capítulo 2 mostramos algumas das aplicações dos algoritmos na resolução de diferentes tipos de problemas. E apresentada uma breve introdução ao conceito de entrada, processamento e saída e também são apresentados os tipos de algoritmos pseudocódigo e fluxograma. No Capítulo 3 são apresentados os tipos de dados básicos e seus desdobramentos na linguagem de programação Java. Além disso, são definidos o conceito, a aplicação e a identificação de variáveis e constantes e é demonstrado o uso dos operadores de atri buição, aritméticos, relacionais e lógicos tanto na notação algorítmica como na lingua gem de programação Java. Nesse capítulo também são exemplificados a construção de expressões de atribuição, aritméticas e lógicas, a ordem de precedência matemática uti lizada na resolução de problemas e o uso da tabela-verdade como recurso facilitador do entendimento do uso dos operadores lógicos. O Capitulo 4 aborda de maneira bastante simplificada alguns dos paradigmas da programação: linear, estruturada e orientada a objetos. No Capítulo 5 - que é aquele que trata dos conceitos relacionados à lógica de programação - são estudados os recursos para entrada e saída de dados e o uso de esttuturas de repetição e seleção. E por meio do uso dessas estruturas que o programador cria rotinas para controle do fluxo dos dados em seus programas - rotinas que possibilitem o acesso ou não a determinadas informações e que implementem estruturas de dados mais sofisticadas. O Capítulo 6 trata das estruturas de dados estáticas e homogêneas, isto é, dos vetores e matrizes, e das operações que estas suportam. Também são abordadas algumas aplicações práticas. No Capítulo 7 são abordados alguns recursos que melhoram a legibilidade do código de programação ou do algoritmo e que podem possibiJitar a reutilização do códi go por outros programas; estes recursos são os procedimentos, as funções e os parâme tros que são passados para eles. No Capítulo 8 são apresentados recursos para facilitar a ordenação das informa ções que serão armazenadas ou manipuladas e para possibilitar a busca de informações específicas. O Capítulo 9 trabalha as técnicas de criação e manipulação de arquivos-texto seqüenciais e randômicos. O Capítulo I O aborda as estruturas de dados, pilhas, filas e árvores de maneira simples e com exemplos que ilustram, passo a passo, como criar e utilizar essas estruturas. Por último, no anexo, são apresentados alguns recursos do Java. '
'
Assim, este livro procura de maneira bastante simples abordar algumas questões que, por vezes, parecem muito complexas ao programador iniciante; todos os assuntos são explicados e exemplificados por meio de soluções comentadas. Ao final de cada
INTRODUÇÃO
XV
capítulo existem exercícios propostos, os quais tem como objetivo fixar o conteúdo estudado ou então, no caso de exercícios mais sofisticados, complementar o aprendiza do. No site da editora estão disponíveis outros exercícios complementares e desafios. Esperamos, com este livro, poder contribuir para o aprendizado dos nossos leitores. Sandra Gavioli Puga e Gerson Rissetti
C
A
,
PIT
UL
O
INTRODUÇÃO '
/
A LOGICA
� Introdução à lógica � Aplicações da lógica � Exercícios para fixação � Exercícios complementares
OBJETIVOS:
Abordar o conceito de lógica como ciência; desta car o uso da lógica de maneira muitas vezes incon dicional, nas tarefas do dia-a-dia; usar o raciocínio lógico para a tomada de decisões e para a resolução ele problemas.
O
filósofo grego Aristóteles é considerado o criador da lógica. No entanto, ele não a chamava assim, denominava-a 'razão'. O termo 'lógica' só passou a ser utiU zado mais tarde. A palavra 'lógica' é originária do grego fogos, que significa linguagem racional. De acordo com o dicionário Michaelis, lógica é a análise das formas e leis do pensa mento, mas não se preocupa com a produção do pensamento, quer dizer, não se preocu pa com o conteúdo do pensamento, mas sim com a forma deste, isto é, com a maneira pela qual mn pensamento ou uma idéia são organizados e apresentados, possibilitando que cheguemos a uma conclusão por meio do encadeamento dos argumentos. Os argumentos podem ser dedutivos ou indutivos. Os argumentos indutivos são aqueles com que, a partir dos dados, se chega a uma resposta por meio da analogia, ou
- E ESTRUTURAS DE DADOS LOGICA DE PROGRAMAÇAO '
2
seja, pela comparação com algo conhecido, porém esse tipo de raciocínio não oferece certeza de que a resposta será de fato verdadeira. E necessário conhecer os fatos ou as situações para que se possa fazer a comparação. Por exemplo: ontem não havia nuvens no céu e não choveu. Hoje não há nuvens no céu, portanto não vai chover. Já os argumentos dedutivos são aqueles cuja conclusão é obtida como conse qüência das premissas, isto é, por meio da análise das situações ou fatos, pode-se obter a resposta. Trabalha-se com a forma das sentenças, sem que haja necessidade do conhe cimento prévio das situações ou fatos. Por exemplo: Joana é uma mulher. As mulheres são seres humanos. Logo, Joana é um ser humano. A lógica nos permite caminhar pelos limiares das diversas ciências! '
1.1
/
/
0 U S O DO RACIOCI N I O LOGICO NO DIA-A-DIA
Desde os tempos primitivos o homem utiliza-se do raciocínio lógico para a rea lização das suas atividades. Isso é comprovado pelo fato de ele ter estabelecido seqüên cias adequadas para a realização das suas tarefas com sucesso. Podemos citar alguns exemplos relacionados às suas atividades do dia-a-dia: •
•
•
1.2
Uma pessoa adulta, para tomar banho, primeiro tira a roupa para não molhá la e também para estabelecer contato direto entre sua pele e a água. Uma criança, desde pequenina, aprende que, para chupar uma bala, é preciso tirá-la da embalagem. Foi utilizando-se do raciocínio lógico que o homem conseguiu criar a roda! /
'
/
0 USO DA LOGICA A P L I CADA A I N FO R MATICA
A lógica é aplicada a diversas ciências, tais como a informática, a psicologia e a física, entre outras. Na informática e na computação, apJjca-se a todas as suas áreas, para a construção e funcionamento do hardware e do software. Por exemplo, na constnt ção de um circuito integrado para o teclado, trabalha-se com o conceito de portas lógi cas para a verificação da passagem ou não de pulsos elétricos, a fim de que seja estabe lecida uma comunicação entre os componentes. Já na constmção de software, é por meio do raciocínio lógico que o homem constrói algoritmos que podem ser transforma dos em programas de computador capazes de solucionar problemas cada vez mais complexos. E justamente esse assunto que estudaremos neste livro. ,
NOTA:
Hardware- Parte física do computador- peças. Exemplo: teclado. Software- Parte lógica do computador- programas. Exemplo: Windows. Algoritmo - Seqüência de passos ordenados para a realização de uma tarefa. Programa - Conjunto de instruções legíveis para o computador e capazes de
realizar tarefas.
-
"
...
"'
CAPITULO I - INTRODUÇAO A LOGICA
3
Para nos auxiliar na resolução dos problemas de construção de algoritmos apli cados à informática, faremos uso da lógica formal dedutiva. No entanto, para que sejam reunidos dados para a solução dos problemas, muitas vezes utilizaremos o raciocínio lógico indutivo. Como foi visto anteriormente, a lógica preocupa-se com a forma da construção do pensamento. Isso permite que se trabalhe com variáveis para que se possa aplicar o mesmo raciocínio a diferentes problemas. Por exemplo: Gerson é cientista. Todo cientista é estudioso. Logo, Gerson é estudioso. Substituindo as palavras 'Gerson' e 'estudioso' por A e B: A é cientista. Todo cientista é B. Logo, A é B. NOTA:
Variáveis- Vide o Capítulo 3.
O raciocínio lógico nos conduz a uma resposta que pode ser 'verdadeiro' ou 'falso'. Na construção de algoritmos para a solução de problemas computacionais, tra balha-se com esse tipo de raciocínio. As informações a ser analisadas são representadas por variáveis que posteriormente receberão valores. As variáveis, por sua vez, represen tarão as premissas. Por exemplo: Dados dois valores quaisquer, deseja-se saber qual é o maior. Os dois valores são representados pelas variáveis A e B. Analisa-se o problema a fim de averiguar qual é a melhor manei_ra de descobrir a solução, então se monta a seqüência para que seja verificada a questão. Para descobrir a solução, pode-se partir de problemas similares já resolvidos e, por analogia, aplicar o mesmo método ao problema atual, ou podem-se estudar formas de resolvê-lo buscando dados com especialistas no assunto em questão. Nesse caso, vamos substituir as variáveis por valores conhecidos, apenas como modelo para facilitar o entendimento do raciocínio aplicado: A será substituída por 7 e B, por 19. Para que seja verificado o maior valor, deve-se fazer uma compara ção, por exemplo: 7 é maior do que 19? Logo tem-se a resposta: falso. Então, pode-se concluir que 1 9 é o maior número entre os dois. I.: EM BRE-sE:
A resposta a uma questão deve ser 'verdadeiro' ou 'falso'; nunca pode ser as duas opções ao mesmo tempo.
-
'
4
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
Quando os valores são desconhecidos, na representação para a solução do problema, trabalha-se apenas com as variáveis: A é maior do que B? Se a resposta é 'verdadeiro', A é o maior valor. Se a resposta é 'falso', B é o maior valor.
NOTA:
1 .3
Não está sendo considerada a possibifidade de os vafores de A e 8 serem iguais, por se tratar apenas de um exempfo para a construção do raciocínio, não sendo (evada em conta a compfexidade do probfema em questão para o caso de uma impfementação. /
�
EXERCICIOS PARA FIXACAO .;,
1 . Dadas as premissas a seguir, verifique quais são as sentenças que represen tam a conclusão correta: I - Cavalos são animais. Animais possuem patas. Logo: a) Cavalos possuem patas. b) Todos os animais são cavalos. c) Os cavalos possuem quatro patas. 1 1 - Retângulos são figuras que têm ângulos. Temos uma figura sem nenhum ângulo. Logo: a) Essa figura pode ser um círculo. b) Não é possível tirar conclusões. c) Essa figura não é um retângulo.
III Se o verde é fotte, o vermelho é suave. Se o amarelo é suave, o azul é médio. Mas ou o verde é forte ou o amarelo é suave. Forte, suave e médio são as únicas tonalidades possíveis. Logo: -
a) O azul é médio. b) Ou o vermelho é suave ou o azul é médio. c) O amarelo e o vermelho são suaves. 2.
Responda: a) Qual é a importância da lógica para a informática? b) Descreva algumas atividades relacionadas ao seu dia-a-dia nas quais o uso da lógica se faz presente e perceptível. c) O que são argumentos? d) Qual é a diferença entre argumentos dedutivos e argumentos indutivos? Exemplifique.
"
CAPITULO 1
_
- INTRODUÇAO
,
,
5
A LOGICA
3. Analise e descreva uma maneira de mover os discos do pino A para o pino C,
mantendo a mesma ordem. Em hipótese nenhuma um disco maior poderá ficar sobre um menor. Para que um disco seja movido de A para C, deve-se passar pelo pino B e vice-versa.
A
1 .4
B
c
/
EXERCICIOS CO M P L E M E NTARES 1 . Dadas as premissas a seguir, verifique quais são as sentenças que represen tam a conclusão correta: I Você está dirigindo seu carro. Se brecar repentinamente, um caminhão baterá na traseira dele. Se não brecar imediatamente, você atropelará uma criança que está atravessando a estrada. Logo: -
a) As crianças devem afastar-se das estradas. b) O caminhão baterá na traseira de seu carro ou você atropelará a criança. c) O caminhão vai muito depressa. - Somente quando B é X, K é Z. E é X ou Z somente quando K não é Z. Duas letras não podem ser uma só. Logo: TI
a) Quando B é X, E não é X nem Z. b) Quando K é Z, X ou Z é E. c) Quando B não é X, E não é X nem Z. 111 - Quando B é maior que A, J é menor que A. Porém, A nunca é maior que B e jamais é igual a B. Logo: a) J nunca é menor que B. b) J nunca é menor que A. c) J nunca é maior que B. IV - Todas as plantas verdes têm clorofila. Algumas coisas que têm clorofila são comestíveis. Logo: a) Alface é comestível. b) Algumas plantas verdes são comestíveis. c) Alface tem clorofila.
'
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
6
2.
De acordo com as pistas de cada uma das histórias, descubra o que se pede: a) As amigas de Maria organizaram um chá-de-panela para comemorar seu casamento, que estava próximo. Como é de costume, cada amiga compa receu à reunião com um presente devidamente embrulhado. O chá-de panela consiste em uma brincadeira que é feita com a noiva, na qual ela deve adivinhar o presente contido em cada embrulho que recebe. Se errar, recebe castigos. Sua tarefa é descobrir o presente que cada amiga levou. De acordo com as dicas abaixo, preencha a tabela. Maria adivinhou os presentes de Janete e Sandra. Maria não adivinhou o conteúdo do embrulho que continha uma garrafa térmica, por isso teve de vestir uma fantasia de coelhinha. Márcia pediu que Maria dançasse a dança da garrafa. Renata a castigou com uma maquiagem de palhacinho. - Maria acertou os embrulhos da frigideira e da jarra para suco. O faqueiro não foi presente de Izabel. Por ter errado o caldeirão, Maria acabou ficando embriagada. - No embrulho de Sandra estava escrito 'frágil' e isso facilitou muito a descoberta. Colega
Presente
b) Oito carros de equipes diferentes estão alinhados lado a lado para uma corrida. De acordo com as pistas abaixo, descubra a ordem dos carros para a largada e a cor de cada carro. (Obs.: a cor utilizada não é a cor original das equipes.) O carro branco está à esquerda do Lotus. O carro da equipe Ferrari está entre os carros vermelho e branco. O McLaren é o segundo carro à esquerda do Ferrari e o primeiro à direita do carro azul. O Sauber não tem can·o à sua direita e está logo depois do carro preto. O carro preto está entre o Sauber e o carro amarelo.
"
CAPITULO 1
-
- INTRODUÇAO
....
_,
A LOGICA
7
- O Jaguar não tem cano algum à sua esquerda e está à esquerda do carro verde. '
- A direita do carro verde está o Renault. - O Jordan é o segundo carro à direita do carro prata e o segundo à esquerda do carro laranja. O Toyota é o segundo carro à esquerda do Minardi. 3. Um pastor deve levar suas três ovelhas e seus dois lobos para o pasto que fica
ao sul da região. Ele deve levar também a provisão de alimentos para as ovelhas, que consiste em dois maços de feno. No entanto, no meio do cami nho existe um grande rio cheio de piranhas e o pastor tem apenas um peque no barco à sua disposição, que lhe permite levar dois 'passageiros' de cada vez. Considere como passageiros as ovelhas, os maços de feno e os lobos e considere que, se as ovelhas ficarem em menor número do que os lobos, serão comidas e que, se o feno ficar com as ovelhas sem um lobo por perto, as ovelhas comerão o feno. Ajude o pastor a atravessar o rio e preservar suas posses.
C
A
"
PIT
UL
Java_cap-02
O
INTRODUÇÃO AOS ALGORITMOS
� Introdução aos algoritmos � Tipos de algoritmos � Pseudocódigo � Fluxograma � Exercícios para fixação � Exercícios complementares
OBJETIVOS:
Mostrar as aplicações dos algoritmos para resolu ção de diferentes problemas; especificar a importân cia dos algoritmos para a resolução de problemas computacionais; abordar os conceitos de entrada, processamento e saída do ponto de vista computa cional; definir os tipos de algori tmos a serem utili zados neste I ivro (pseudocódigo e fluxograma).
U
m algoritmo é uma seqüência lógica de instruções que devem ser seguidas para a resolução de um problema ou para a execução de uma tarefa. Os algoritmos são amplamente utilizados nas disciplinas ligadas à área de ciências exatas. tais como matemática, física, química e informática, entre outras, e também são utilizados com muito sucesso em outras áreas. No dia-a-dia, as pessoas utilizam-se de algoritmos de maneira intuitiva, sem que haja necessidade de planejar previamente a seqüência de passos para a re solução das tarefas quotidianas. Dentre os inúmeros exemplos existentes, podemos citar:
'
-
9
CAPITULO 2 - INTRODUÇAO AOS ALGORITMOS
1 . Quando uma dona de casa prepara um bolo, segue uma receita, que nada mais é do que um algoritmo em que cada instrução é um passo a ser seguido para que o prato fique pronto com sucesso: Bata quatro claras em neve. Adicione duas xícaras de açúcar. Adicione duas xícaras de farinha de trigo, quatro gemas, uma co lher de fermento e duas colheres de chocolate. Bata por três minutos. Unte uma assadeira com margarina e farinha de trigo. Coloque o bolo para assar durante vinte minutos em temperatura média. 2. Um motorista que necessita efetuar a troca de um pneu furado segue uma
rotina para realizar essa tarefa: Verifica qual pneu está furado. Posiciona o macaco para levantar o carro. Pega o estepe. Solta os parafusos. Substitui o pneu furado. Recoloca os parafusos. Desce o carro. Guarda o macaco e o pneu furado. 3. Um matemático, para resolver uma equação qualquer, utiliza passos pré-de
terminados que conduzem à obtenção do resultado.
2. 1
....
'"'
ALGOR I T M O S A P L ICADOS A SOLUÇAO D E PROBLEMAS COM PUTACIONAIS
Os algoritmos são amplamente utilizados na área da computação, seja na elabo ração de soluções voltadas à construção de interfaces, software e hardware, seja no pla nejamento de redes. Os algoritmos também constituem uma parte importante da docu mentação de sistemas, pois descrevem as tarefas a serem realizadas pelos programas.
2.2
T I POS D E ALGOR I T MOS
Existem diversos tipos de algoritmos. Dentre eles, podemos citar: pseudocódigo, descrição narrativa, fluxograma e diagrama de Chapin.
-
'
10
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
•
•
•
•
O pseudocódigo utiliza linguagem estruturada e se assemelha, na forma, a um programa escrito na linguagem de programação Pascal. O pseudocódigo é também denominado por alguns autores como português estruturado, embora existam pequenas diferenças de metodologia entre ambos. É bastante utilizado para representação da resolução de problemas computacionais. A descrição narrativa utiliza linguagem natural para especificar os passos para a realização das tarefas. Isso dá margem a más interpretações e ambigüi dades. Não é muito utilizada. O fluxograma é uma forma universal de representação, pois se utiliza de figuras geométricas para ilustrar os passos a serem seguidos para a resolução dos problemas. Bastante utilizado, é também chamado por alguns autores de diagrama de blocos. O diagrama de Chapin, também conhecido como diagrama Nassi Shneiderman ou diagrama N-S, apresenta a solução do problema por meio de um diagrama de quadros com uma visão hierárquica e estruturada. Esse tipo de diagrama não é muito utilizado, pois é muito difícil representar recur sividade, entre outros procedimentos.
Neste livro, serão abordadas as duas formas mais comuns de representação de soluções para problemas computacionais: pseudocódigo e fluxograma. A seguir, serão descritas as características de cada um.
2.3
"
PS E U DOCODIGO
O pseudocódigo é um tipo de algoritmo que utiliza uma linguagem flexível, intermediária entre a linguagem natural e a linguagem de programação. E utilizado para organizar o raciocínio lógico a ser seguido para a resolução de um problema ou para definir os passos para a execução de uma tarefa. E também utilizado para documentar rotinas de um sistema. A palavra 'pseudocódigo' significa 'falso código'. Esse nome se deve à proximi dade que existe entre um algoritmo escrito em pseudocódigo e a maneira pela qual um programa é representado em uma linguagem de programação. O Exemplo 2.1 propõe um problema simples para o qual será desenvolvido o algoritmo em pseudocódigo. ,
'
2.3. 1
-
I D E N T I FI CAÇAO DO ALGORITMO
Todo algoritmo representado por um pseudocódigo deverá ser, primeiramente, identificado. Para se identificar ou nomear o algoritmo, recomenda-se: •
Não utilizar espaços entre as letras. Por exemplo: para um cadastro de clien tes, o correto seria cad_cli ou cadcliente. O caractere 'sublinha' ou 'underline' ( _ ) pode ser utilizado para representar o espaço entre as letras.
-
'
1 1
CAPITULO 2 - INTRODUÇAO AOS ALGORITMOS
Desenvolver um pseudocódigo para ler o nome, a idade, o cargo e o salário
ExEMPLo 2 . 1 :
de 50 pessoas e verificar quantas possuem idade inferior a 30 anos e
um
salário superior a R$ 3.000,00.
Identificação do algoritmo
Algoritmo Exemplo 2 . 1 _
Var nome , cargo :
Declaração das variáveis
literal
idade , n_pessoas, tot_pessoas : inteiro salario: real
Corpo do algoritmo
Início n_pessoas
(- 1
tot_pessoas f- o
Enquanto (n_pessoas 5 - Se o valor de a for maior do que 5, retornará falso. Caso contrário, retornará
1
verdadeiro.
I TABELA s i Operadores lógicos
verdade iro, o valor verdadeiro será atribuído à variável A. Em quaJquer outra circunstância, o valor falso será atribuído a A. Deve-se observar que, primeiramente, são avaliadas as expressões de comparação B < 8 e C = 3 e, posteriormente, os resultados dessas duas expressões são associados por meio do operador e , obtendo .
.
se o resultado final. Isso se deve ao fato de existir uma precedência entre os operadores relacionais e os lógicos. Os operadores relacionais são avaliados primeiro e, posterior mente, os lógicos. Normalmente, além da existência de precedência entre operadores de tipos diferentes, operadores do mesmo tipo possuem, também, uma precedência. A Ta bela 6 demonstra essa relação.
Operador
Observação
( )' [ ]
Parênteses e colchetes são usados para agrupar expressões, determinando precedência, a exemplo das expressões matemáticas.
" ou
Operador aritmético de potenciação.
*
**
,I
Operadores aritméticos de multiplicação e divisão.
+' -
Operadores aritméticos de adição e subtração.
f-
Operador de atribuição.
=, , < = , > = ,
Operadores relacionais.
.
.nao.
Operador lógico de negação.
.e.
Operador lógico e.
.ou.
Operador lógico ou. I TABELA
si
Precedência de operadores
'
'
CAPITULO 3 - CONCEITOS BASICOS SOBRE ALGORITMOS
25
Dessa forma, a expressão: A f- B + 2 > 5
.
u
o
C 4
.
.e.
D
-
0
seria avaliada na seguinte ordem: • c 4 • D •
[1]
o
=
[2]
[ l ] . e . [2]
[3]
• B + 2 •
[4] > 5
•
[5]
.
• A (LEMBRE-sE:
3.5
[4] [5]
ou . [3]
[6]
[6]
A precedência matemática também deve ser considerada na imple mentação dos algoritmos.
TABELA-VERDADE
A tabela-verdade expressa o conjunto de possibilidades existentes para a com binação de variáveis ou expressões e operadores lógicos. Um exemplo de combinação entre variáveis é A >= 5 . e . B ! = 1 O , onde A e B são as variáveis, > = e ! = são os operadores relacionais e . e . é o operador lógico. Um exemplo de combinação entre expressões é A + B ! = X - 1 O. A tabela-verdade é utilizada para facilitar a análise da combinação dessas expressões ou variáveis, conforme pode ser verificado a seguir: Operador &&
Expressão algoritmo A - 5 B 9 A Expressão 9 A A -- 5 B ! em Java Resultados .v. . v. . poss1ve1s =
'
==
5
(.e.) .e.
5
B 9 A - 5
&& B !
< . ou . )
II
=
9
.ou.
B 9
I I B !
A -- 5
I
=
9
( . não.)
.não. A - 5
! A --
.v.
.v .
. f.
.v.
.f.
.f.
.v .
. f.
. f.
.v.
.f.
.v .
. v.
.f.
. f.
. f.
.
f
. v.
.
5
!TABELA 7 1 Tabela-verdade
Na tabela, pode-se verificar que as expressões A = 5 e B ! = 9 podem assumir quatro possibilidades. Ou seja, ambas podem ser verdadeiras (primeira linha dos resul tados possíveis), a primeira pode ser verdadeira e a segunda falsa, a primeira pode ser falsa e a segunda verdadeira ou ambas podem ser falsas. Essas combinações dependem, p01tanto, dos valores atribuídos às variáveis A e B.
- E ESTRUTURAS DE DADOS LOGICA D E PROGRAMAÇAO '
26
Submetendo essas expressões aos operadores lógicos ( && - e, I I - ou, ! - não), obtêm-se valores diferentes, dependendo do resultado que cada uma das expressões assumir individualmente. Assim, considerando a primeira linha de resultados possíveis, onde A = 5 é verdadeiro e B 9 também é, obtemos os seguintes resultados: •
5 é verdadeiro e B verdadeiro para A 5 . e . B 9 : se A < > 9 também é, o resultado associado com o operador && também é; =
=
•
verdadeiro para A = 5
. ou . B 9 : se A = S é verdade iro e
•
falso para .não. A = 5 : se A = 5 é verdadeiro,a negação é falso.
B 9 também é, o resultado associado com o operador l i também é;
Deduz-se que, para o operador &&, o resultado será verdadeiro somente se ambas as expressões associadas assumirem o resultado verdadeiro. Por outro lado, para o operador I I , o resultado será verdadeiro se pelo menos uma das expres sões associadas assumir o resultado verdadeiro.
3.6
�
/
EXE RCICIOS PARA FIXAÇAO 1 . Dadas as expressões a seguir, identificar o resultado verdadeiro ou falso
que cada uma delas retornaria, em função dos valores dados. Exemplo: Supondo que à variável A seja atribuído o valor 2 e à variável B seja atribuído o valor 7 : A = 2
.e. B = 5
Resultado: falso (para A=2, o resultado é verdadeiro; para B=5, o resultado é falso. Como o operador é . e . , o resultado final é falso). Considerando os mesmos valores atribuídos a A e B, avalie as expressões a . seguir: � A = 3
.e. B = 7
b) A < 3
. ou. B 7
c) A 2 . ou . B
7
Verifique se as variáveis abaixo possuem nomes corretos e justifique as alter nativas falsas: a) n#l
b) tempo
c) n_l
d) $din
e) n 1
f)
K2K
g) nl
h) U F
i)
2nome
'
'
CAPITULO 3 - CONCEITOS BASICOS SOBRE ALGORITMOS
k) nome2
j) dep
27
l)
val#r
3. Sabe-se que o uso incorreto da precedência de operadores ocasiona erros.
Pensando nisso, avalie as expressões a seguir e: a) classifique a ordem em que as operações deverão ser executadas; b) determine o resultado das operações. Considere os seguintes valores para as variáveis: A f- 8· B f- 5· C f - -4 · D f- 2 '
'
'
a) Del ta f- B2 - 4 * A * c b) J f- "Hoje" "HOJE" c) Media f- ( A + B + C + D ) I 4 d) Medi a f- A + B + C + D I 4 e) Resultado f- A mod D I 5
D Resultado f- (A mod D ) I 5 g) X f- ( A + B ) - 1 O * C h) X f- A
10 * C
+
B
-
i) Y f- A >
8
.e. B
+
C > D
j) Y f- A > 3 * 2 . ou . B + C D
3.7
/
EXERCICIOS COM P L E M E NTARES 1 . Considere a seguinte atribuição de valores para as variáveis: A f- 3, B f- 4 e C f-
8
Avalie as expressões a seguir indicando o resultado final: verdadeiro ou falso. - 8 .e. c -
a) A > 3
b) A < > 2 . ou . B
= 2 c) A - 3 d) A e) A
.e. 8
�
5 .e. c - 8
. nao . B 2
D B > A . e . c A g) A > B . ou . B
<
5
- c h) A B . e . B -
i) c > 2 . ou . A < B
j) A > B . ou . B > A . e . c B
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
28
2. Complete a tabela-verdade a seguir: Operador
Expressão
A
-
4
B 5 A
4
-
B 5 A
.e.
�
. ou.
.e. -
. nao .
4 . ou . B 5 .não. A
Resultados •
pOSSJVeis
3. Construa a tabela-verdade para as expressões: a) A >= 3 . ou . B
5
-
b) A 9 . e . B = 1
. e . B 5
d) A > 3 4.
-
. ou . c < 8
Dada a declaração de variáveis: inteiro;
Var A , B , C :
real;
X , Y, Z :
Nome , Rua : literal; L1 :
lógico;
e atribuindo-se a essas variáveis os valores: A � 1
X � 2,5
Nome � "Pedro"
B � 2
y � 10 , 0
Rua
c � 3
z � -1, 0
L1 � . v .
�
"Girassol"
Determine o resultado das expressões a seguir: a) Nome = Rua � X > Y . e . C =
(A
+
c) )
�
e) . nao . L1
t) . nã o . c
-
B .e. X
+
y =1) {
59. 60.
int c ;
61.
c
62.
System . o u t . println ( "O resultado da operacao e ' :
63.
bat-;
64.
System . o u t . println( "Nivel da bateria:
65.
}
66.
if
=
a * b;
"
+ c);
+ bat ) ;
(bat == 1) { System. out. println ( "Bateria fraca, recarregar ! " ) ;
67. 68.
}
69.
if (bat
70.
==
O) {
System . out . println ( "Robo danificado ! " ) ;
}
71 . 72.
}
73 .
public void divid e ( int a , int b) {
74 .
if
(bat >=1) {
75 .
int c ;
76.
c
77. 78.
System . ou t . println ( " O resultado da operacao e' : bat-;
79.
System . o u t . println( "Nivel da bateria:
80.
}
81.
if
=
a I b;
"
"
+ c) ;
+ bat ) ;
(bat == 1 ) { System . ou t . println ( "Bateria fraca, recarregar ! " ) ;
82. 83.
}
84.
if
85.
(bat
==
0) {
System.out.println ( "Robô danificado ! " ) ;
}
86.
}
87. 88.
"
}
Nesse exemplo, pode-se verificar a criação de uma classe denominada Robo, que herda os atributos e métodos da superclase Robo_superclase (linha 1 ) que possui os atributos declarados nas linhas 3 a 6. Os chamados métodos construtores são responsáveis pela criação das instâncias de classe, ou seja, novos objetos com as carac terísticas da classe Robo. Foram definidas duas formas de criação de instâncias: uma sem passagem de parâmetros (linha 3) e outra com a passagem de parâmetros definindo nome, série e data (linha 9).
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
44 ATENÇÃO!
A palavra Robo refere-se ao nome da classe e deve ser escrita sem acento.
NOTA!
Método é a implementação ou a codificação em uma linguagem de programação de uma operaç,io de Ltm objeto.
O método mudaNome (linha 15) permite a alteração do nome do robô. Esse método recebe como parâmetro o novo nome que o robô deverá assumir. Esse método demonstra a característica de encapsulamento de dados da metodologia, ou seja, so mente é possível alterar o nome de um robô acessando-se esse método. Outros atributos de Robo, como o número de série, por exemplo, não poderão ser alterados. Uma vez definido quando da instanciação de um novo robô, o número de série não poderá mais ser alterado, visto que não há um método que permita esse tipo de alteração. Preserva se, assim, a integridade dos dados. Robo também executa algumas operações aritméticas como, por exemplo, a soma de dois números inteiros fornecidos, exibindo o resultado. Isso foi implementado nas linhas 27 a 42. A exibição do resultado se dá na linha 32, onde se mosn·a a literal: "O resultado da operação é : ", seguida do valor da variável c. Quando da execução de uma operação aritmética, a bateria do robô, que se ini cia com a carga 5, é decrementada, o que denota um desgaste. Isso é feito pelo comando na linha 38. Após a execução de uma seqüência de quatro operações aritméticas, o Robo atinge a carga da bateria igual a O (zero). Nesse caso, é exibida a mensagem: "Robo dani ficado! " , por meio dos comandos nas linhas 39 a 4 1 . A seqüência de código a seguir executa uma espécie de teste da classe Robo, no qual são criadas duas i.nstâncias da classe, Rl e R2, são chamados alguns métodos e são executadas algumas operações aritméticas. 1.
class TestaRobo
2.
{
3.
public static void main ( String [ ) args ) {
4.
System. out . println ( "Testando Robo" ) ;
5.
Robo R1
6.
System. out . println ( "Robo :
7. 8.
Rl . soma ( 3 , 2 ) ; R1 . subtrai ( 8 , 2 ) ;
9.
R 1 . multiplica ( 3 , 4 ) ;
=
new Robo ( } ;
10.
Rl . divide ( 8 , 2 ) ;
11.
Rl . divide ( 6 ,
" + Rl . mostraNome ( ) ) ;
3) ;
12 . 13.
Robo R2
14.
System . o u t . println ( "Testando Robo" ) ;
15.
System . o u t . println( "Robo :
16.
R2 . soma ( 5 , 4 ) ;
17 .
R2 . multiplica ( 3 , 5 ) ;
18.
R2 . mostraTudo ( ) ;
=
new Robo ( "D2 8 8 " ,
2,
" 0 5 / 1 1 / 2 0 02 " ) ;
" + R2 . mostraNome ( ) ) ;
-
'
CAPITULO 4 - CONCEITOS DE PROGRAMAÇAO
}
19.
20.
45
}
A instanciação de um objeto da classe Robo é feita por meio do código que está nas linhas 5 e 1 3; em cada caso, foi usado um dos dois métodos constmtores possíveis. Deve-se notar a chamada de um método, como o que exibe o nome do robô (linha 6), utilizando-se a notação: Objeto. método, no caso, Rl . mos traNome ( ) .
4.4
/
'"'
EXERCICIOS PARA F IXAÇAO 1 . Faça um comparativo entre a programação estmturada e a programação orientada a objetos e cite as vantagens de cada uma. 2 . Quais são as principais características da programação estruturada? 3. Quais são as principais características da programação orientada a objetos? 4.
Quais são as principais características da programação linear?
5. Cite alguns exemplos de linguagens de programação orientada a objetos, estruturada e linear.
4.5
/
EXE RCICIOS COM P L E M E NTARES 1 . Descreva alguns exemplos de atividades nas quais seja possível o uso do recurso de polimorfismo. 2. Descreva alguns exemplos de atividades nas quais seja possível o uso do
recurso de encapsulamento. 3.
Descreva alguns exemplos de atividades nas quais seja possível o uso do recurso de herança.
C
A
"'
PIT
UL
O
CONSTRUÇÃO DE ALGORITMOS : ESTRU T U RAS DE CONTRO LE � Entrada e saída de dados � Estr uturas de seleção (de decisão ou de desvio) � Estr uturas de repetição � Exemplos e exercfcios parafixação
OBJETIVOS:
Abordar as técnicas para entrada e saída de dados e as estruturas para controle do fluxo de dados em pseudocódigo, fluxograma e na linguagem de pro gramação Java.
I
magine que pretendemos construir um aparelho para realizar uma ação qualquer na casa do comprador. Como não moramos na casa dos possíveis compradores, não sabemos se o aparelho será utilizado da maneira que planejamos e, portanto, devemos prever os possíveis comportamentos do aparelho para que cumpra suas tarefas sem pro blemas para o comprador. Quando fazemos um programa, devemos saber constmí-lo para prever qualquer intenção que o usuário tenha ao utilizar esse programa. Entrada e saída de dados
Entrada
Processamento
Saida
-
'
CAPITULO 5 - CONSTRUÇAO D E ALGORITMOS: ESTRUTURAS DE CONTROLE
47
É importante ressaltar a seqüência de fatos que fundamentam a lógica computa cional: a entrada dos dados que serão processados para obter a saída. Os dados que entram em processamento sofrem transformações resultantes do processo e uma saída é produzida, representando a solução de um problema. Vamos fazer uma breve análise desses dois aspectos de um programa.
5.1
E N T RADA
A entrada elementar de dados é feita por meio do teclado (dispositivo-padrão) e é representada por: Ler
(variavel)
Para uma variável inteira, por exemplo, esse comando procura uma seqüência de caracteres que representem os dígitos de um inteiro eventualmente precedidos por um sinal + ou - . Nesse caso, são descartados eventuais caracteres brancos e, a partir do primeiro caractere não branco, a rotina de leitura assume que encontrou uma cadeia de caracteres que está de acordo com a sintaxe dos inteiros. Se isso não acontece, ocorre um erro fatal e a execução do programa é interrom pida. Se, por outro lado, a rotina encontra um caractere que atenda à sintaxe de um intei ro, ela continua a consumir caracteres até que encontre algo diferente, como um caractere branco, por exemplo. Durante o processo, a seqüência de caracteres que satisfaz a sintaxe de um intei ro é convertida em um valor binário. Ao final do processo, o valor binário resultante é armazenado na posição correspondente à variável inteira para a qual a rotina de entrada procurou um valor. Quando falamos que caracteres brancos são desca1tados, estamos apenas exemplificando. Isso ocorre também com caracteres de formatação de texto como o de tabulação, o de mudança de linha e o de 'retorno de carro' . Ao digitarmos dados pelo teclado, eles são 'ecoados' na tela do monitor do computador, isto é, são mostrados na tela conforme vão sendo digitados. Enquanto não se pressiona uma tecla de mudança de campo (ENTER para DOS ou TAB para telas gráficas), o processo de leitura não é disparado e o programa suspende a execu ção do comando de leitura que está solicitando dados do usuário. Ao ocorrer o disparo pelo pressionar da tecla ENTER (ou TAB), a execução do programa é retomada nesse ponto. No caso particular da linguagem Java, todas as variáveis lidas por meio do tecla do são reconhecidas como caracteres da tabela UNICODE. Como a linguagem é rigoro sa quanto aos dados que irá manipular, para ler uma variável de um tipo qualquer, deve se utilizar um processo denominado coerção, que nada mais é do que a produção de um valor com o tipo diferente do original. Essa coerção é realizada por meio de recursos especiais do Java, que podem ser consultados no Anexo.
'
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
48 ,
5.2
SAlDA '
E claro que um computador e toda a sua programação não seriam de nenhuma utilidade se o programa não mostrasse o resultado das operações. O dispositivo-padrão de saída é o monitor do computador, e essa saída é representada com o comando: Mostrar (variavel)
A maioria das linguagens de programação possui recursos que permitem fazer uma formatação básica da saída de tela com comandos que escrevem na mesma linha ou 'pulam' para a linha inferior. ExEMPLo s. 1:
Como é costume, o primeiro programa que se aprende a fazer em qualquer linguagem é um aplicativo que mostra uma frase na tela: "Alô Mundo!" Nesse programa não é necessário o uso de variáveis.
Pseudocódigo: 1. 2.
3. 4.
Algoritmo Primeiro Início Mostrar ( "Alô Mundo ! " ) Fim.
Na linha 1 o algoritmo é identificado. As linhas 2 e 4 representam o início e o fim do algoritmo, e a linha 3 é a ação que o algoritmo tem que realizar. Fluxograma: Início
"Alô Mundo!"
Fim
Java: 1.
2.
class Primeiro { public static void main ( String args [ ) ) { System . out .println ( "Alô Mundo ! ") ;
3.
4.
5.
} }
Sobre o código: 1. class Primeiro indica o nome do programa. No caso do Java, todos os programas são classes.
CAPÍTULO 5 - C ONSTRUÇÃO D E ALGORITMOS: ESTRUTURAS DE CONTROLE
2.
49
publ ic static void main ( String args [ ] ) indica o bloco de
instruções que serão executadas seqüencialmente quando o programa for re quisitado pelo usuário. Todo aplicativo escrito em Java deve possuir um bloco indicado dessa maneira para poder ser executado. 3. System . out . print l n ( "Alô
Mundo ! " ) é a instrução que ordena a
exibição da frase na saída do sistema. As chaves { e } indicam início e fim de bloco, respectivamente. CU IDADO!
A linguagem Java é sensível a maiúsculas e minúsculas. Isso quer dizer que as palavras reservadas devem ser escritas exatamente como são definidas! class "# Class, public "# Public "# PUBLIC e assim por diante.
EXEMPLO 5.2:
programa a seguir pergunta qual é o nome do usuário e o escreve nova mente na tela. O
Pseudocódigo: 1.
Algoritmo ExEntrada
2.
Var
3. 4.
nome : literal Início
5.
Mostrar ( "Qual o seu nome ? " )
6.
Ler (nome)
7.
Mostrar (nome)
8.
Fim.
Neste exercício é necessário o uso de uma variável para representar o armazena mento do nome do usuário; a declaração dessa variável está sendo feita na linha 3. As linhas 5, 6 e 7 são as ações necessárias para a realização da tarefa; na linha 5 está sendo exibida a mensagem "Qual o seu nome ? " ; as mensagens sempre devem estar entre aspas. Na linha 6 é indicado que deve ser lido (fornecido) um valor para a variável nome. Na linha 7 o conteúdo da variável nome está sendo exibido.
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
50
Fluxograma: Início
"Qual o seu nome?"
nome
nome
Fim
Java: 1.
import j ava . i o . * ;
2.
c1ass ExEntrada {
3. 4.
5.
pub1ic static void main
( String args ( ) ) {
BufferedReader entrada; entrada = new BufferedReader ( new InputStreamReader ( System. in) ) ; String nome ;
6. 7. 8. 9. 10. 11. 12.
try { System . o u t . print1n( "Qual o seu nome?" ) ; nome = entrada . readLine ( ) ; Sy stem. out . print1n ( nome ) ;
} catch (Exception e ) { System . out . println( "Ocorreu
um
erro durante a
leitura ! " ) ;
}
13 . 14.
15.
} }
Sobre o código: 1. A cláusula import indica a utilização do pacote de entrada e saída de dados (j ava . i o . * ) da linguagem Java nesse programa. Embora isso seja desne cessário para a saída de dados, a linguagem requer um tratamento de entrada de dados para sua leitura correta. 2. e 3.
c las s ExEntrada indica o nome do programa e, novamente, publ ic
static void main ( String args [ ) ) indica o blocode instruções
-
'
CAPITULO 5 - CONSTRUÇAO D E ALGORITMOS: ESTRUTURAS DE CONTROLE
51
que serão seqüencialmente executadas quando o programa for requisitado pelo usuário. 4.
e 5. Não se assuste! Nessas linhas estão a declaração e a criação da variável entrada que será utilizada para a leitura do teclado. Isso é necessário para garantir que a leitura seja armazenada na memória com o formato de uma seqüência de caracteres (String) para que seu valor possa ser manipulado sempre da mesma forma. A vantagem dessa sintaxe é que o programador pode utilizar apenas uma variável de entrada e depois convettê-la para os valores desejados quantas vezes forem necessárias.
6.
A variável nome está sendo declarada para receber e armazenar na memória o valor escrito pelo usuário. Como se deseja a entrada de um texto, ela é declarada como do tipo String.
7., 11., 12.
e 13. Definem um bloco de tratamento de erros característico da linguagem Java. Sempre que houver entrada de dados na linguagem Java, um tratamento de erros simjlar será necessário. Para os fins da lógica deste livro, o tratamento será utilizado sempre dessa forma. '
E recomendável que o programa exiba uma frase solicitando ao usuário as informações necessárias para a sua execução. 9.
A variável nome recebe, por meio do método readLine ( ) , o valor que o usuário escreveu. A variável entrada é um objeto que permite a utilização desse método para a leitura. Essa maneira de chamar métodos é típica da orientação a objetos.
10.
Após a leitura da variável, ela é mostrada oa tela como saída de dados.
14.
e 15. As chaves dessas linhas fecham os blocos do método e da classe, res pectivamente.
EXEMPLo 5.3:
O programa a seguir realiza a soma de dois números inteiros dados pelo '
.
usuano. Pseudocódigo: 1.
Algoritmo ExSoma
2.
Var valor1 , valor2 , soma : inteiro
3. 4.
Início
5.
Mostrar ( "Qual o primeiro valor? " )
6.
Ler (valor1)
7.
Mostrar ( "Qual o segundo valor? " )
8.
Ler (valor2 )
9.
soma � valor1 + valor2
10.
11.
Mostrar ( soma )
Fim.
'
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
52
Fluxograma: Início
'
)
"Qual . . o pnme•ro valor?"
(
valor1 I
"Qual o segundo valor?"
(
valor2 I
soma f- valorl + valor2
(
soma
Fim
'
./)
Neste exemplo, além da exibição de mensagens e entrada de dados, ocorre tam bém um processamento determinado pela opemção aritmética de adição entre as variá veis valorl e valor2 e pela atribuição do resultado à variável soma (linha 9). Java: 1.
import java . io. * ;
2.
class ExSoma {
3.
public static void main ( String args [ ) ) {
4.
BufferedReader entrada;
5.
entrada
=
new BufferedReader ( new InputStreamReader
(System. in) ) ;
6. 7.
int valorl, valor2 , soma ;
try {
'
CAPITULO 5
-
-
CONSTRUÇAO D E ALGORITMOS: ESTRUTURAS DE CONTROLE
8.
System .out.print1n( "Qua1 o primeiro valor? " ) ;
9.
valor1
=
Integer . parseint ( entrada. readLine ( ) ) ;
10.
System .out.print1n( "Qual o segundo valor? " ) ;
11.
valor2
12. 13. 14.
=
53
Integer . parseint ( entrada . readLine ( ) ) ;
soma = valor1 + valor2; System.out.println(soma) ; } catch (Exception e ) {
15 .
System .out.println( "Ocorreu um erro durante a leitura ! " ) ;
}
16.
}
17.
18.
}
Repare que as linhas em itálico são exatamente iguais às do programa anterior. Essas linhas são características da linguagem e não afetam a lógica do problema. Sobre o código: Na linha 6 são declaradas três variáveis do tipo inteiro para armazenar os valores inteiros dados pelo usuário e realizar a soma. As linhas 9 e 1 1 recebem os valores lidos do console na forma de texto e os convertem para números inteiros utilizando o método Integer . parseint ( ) , tam bém específico da linguagem Java. Note que, no caso de o usuário digitar um número real ou uma letra., o programa não efetuará um erro fatal devido ao tratamento de erro, mas exibirá uma mensagem de erro para o usuário, sem realizar a conta. Essa mensa gem pode ser personalizada para cada programa. Finalmente, as linhas 1 2 e 1 3 realizam a soma desejada e mostram o resultado na tela.
5.3
,...
,...
E S T RUTURAS D E S E L EÇAO OU D E C I SAO
As estruturas de seleção ou decisão são utilizadas quando existe a necessidade de verificar condições para a realização de uma instrução ou de uma seqüência de ins truções. Os testes de seleção também podem ser utilizados para verificar opções de escolha. A seguir são apresentados exemplos para os dois casos. Suponha que uma pessoa esteja jogando um jogo de computador: 1.
Para que o jogador passe de uma fase (etapa) para a fase seguinte, é necessá rio que se verifique se ele atingiu a pontuação exigida. Assim, existe uma condição para a realização de uma seqüência de instruções para liberar o acesso à próxima fase do jogo.
2.
Ao final do jogo, uma pergunta é feita: "Deseja continuar jogando?" O joga dor poderá escolher entre as respostas sim ou não.
As estruturas de seleção podem ser do tipo simples, composto ou encadeado.
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
54
5.4
'"'
E S T R U T U RAS D E S E L EÇAO S I M P L E S
São utilizadas para verificar se dada condição é atendida: se for, um conjunto de instruções deverá ser executado; se não for, o fluxo da execução do algoritmo seguirá após o fim do bloco de decisão. Toda condição pode ser encarada como uma petgunta que pode ter a resposta verdadeiro ( . v . ) ou falso (. f . ).
NOTA:
Pseudocódigo: Se
(condição)
então
[início do bloco de decisão)
conjunto de instruções Fim-Se [fim do bloco de decisão] Fluxograma:
co ndição
.v.
conjunto de instruções
Java: if
(condição)
{
; } Quando o teste de condição resultar verdadeiro, sempre será exe cutado o primeiro conjunto de instruções encontrado. Caso contrário, isto é, se a condição resultar falso, será realizado o segundo conjun to de instruções, ou seja, o conjunto de instruções após o senão. (Vide o exemplo no item "Estwturas de seleção compostas".)
NOTA:
EXEMPLo 5.4:
Verificar se um número fornecido pelo usuário é ímpar. Se for, exibir a mensagem: "O número informado é ímpar".
Pseudocódigo: 1.
Algoritmo no_impar
2. 3.
Var
4.
Início
no: inteiro
5.
Ler (no)
6. 7. 8. 9.
Se (no mod 2
=
1 ) Então
Mostrar ( "0 número informado é ímpar" ) Fim-Se Fim.
-
'
CAPITULO 5
-
CONSTRUÇAO D E ALGORITMOS: ESTRUTURAS DE CONTROLE
55
Neste exemplo, na linha 6 é feita a avaliação da condição. Como só existe uma instrução a ser realizada (mostrar a mensagem "O número informado é ímpar"), então esta é uma estrutura de seleção simples. Fluxograma: Início
Leia no
"O número informado é ímpar"
Fim
.F.
Java: 1.
import java . io . * ;
2.
c1ass Numimpar
3.
{
pub1ic static void main ( S tring args [ ) ) {
4.
BufferedReader entrada;
5.
entrada
=
new BufferedReader (new InputStreamReader
( System. in) ) ; 6.
int numero ;
7. 8.
try
{ System .out.print1n ( "Qua1 o número? " ) ; numero = Integer.pa rseint (entrada . readLine () ) ;
9.
10.
if
11.
(numero % 2
==
1)
{
Sys tem. out .príntln
12. 13.
}
) catch (Exception e )
14.
("O número informado é ímpar") ;
{
System . out. println ( "Ocorreu um erro durante a leitura! " ) ;
15 .
)
16. 17.
) )
Sobre o código: Na linha 6 é declarada a variável de tipo inteiro que receberá, na linha 9, o valor digitado pelo usuário e que será avaliado no programa. Na linha 10, a condicional avalia se o número é ímpar ao verificar se o resto da divisão desse número por 2 é igual a 1 . Se isso for verdade, então a frase escrita na linha 1 1 será mostrada na tela.
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
56
Observe que % é o operador que determina o resto da divisão e == é o operador que compara o resultado dessa operação com 1 . Em Java, o operador = determina atri buição de valor e o operador == determina comparação de valores. ,..,
ESTRUTURAS D E S E L EÇAO COM POSTAS
5.5
A estrutura de seleção composta prevê uma condição com dois conjuntos de instruções para serem realizados de acordo com a avaliação da resposta: um bloco de ins truções para resposta verdadeiro e um bloco de instruções para resposta falso. Pseudocódigo: Se (condição) então conjunto de instruções A
[conjunto de instruções que será realizado se o teste de condição resultar verdadeiro]
Senão conjunto de instmções B
[conjunto de instruções que será realizado se o teste de condição resultar falso]
Fim-Se
Fluxograma:
condição
.v.
conjunto de
instruções A Fim
.F.
conjunto de
instruções B
Java: if
(condição)
{
;
) else
{
;
) EXEMPLo 5.5:
A empresa XKW Ltda. concedeu um bônus de 20 por cento do valor do
salário a todos os funcionários com tempo de trabalho na empresa igual ou superior a cinco anos e de dez por cento aos demais. Calcular e exibir o valor do bônus.
Para resolver o problema, é necessário conhecer o valor do salário e o tempo de serviço do funcionário. Para isso, serão utilizadas as variáveis salario e tempo, que representarão esses valores. Para armazenar o valor do bônus, será utilizada a variável bonus.
'
CAPITULO 5 - CONSTRUÇAO D E ALGORITMOS: ESTRUTURAS DE CONTROLE -
57
Pseudocódigo: 1.
Algoritmo Premio
2.
Var
3.
salario, bonus : real tempo : inteiro Início
4.
5. 6.
Ler (salario)
7.
10. 11. 12.
Ler ( tempo) Se ( tempo >= 5 ) então bonus f- salario * 0 . 2 0 Senão bonus nnl � -f---' • 0.10 '---
Java: 1. 2. 3.
4.
import java . i o . * ; class Premio { pub1ic static void main (String args [ ) ) {
BufferedReader entrada;
Fim
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
58 5.
entrada
=
new BufferedReader (new InputStreamReader
( System. in) ) ;
6. 7. 8. 9. 10. 11. 12 . 13 . 14. 15. 16. 17 . 18. 19. 20.
float salario, bonus; int
tempo;
try { System. out.println ( "Qual o salário ?") ; salario
=
Fl oat .pa rseFloat (entrada . readLine () ) ;
System. out .println ("Quanto tempo está na
empresa ?") ;
tempo = Integer.parseint (entrada . readLine ( ) ) ; if
( tempo >=
5)
{
bonus - salario
) else
0 . 20f;
{
bonus - salario
} catch (Exception e)
* O . l Of; ("0
System . o ut .println
}
*
valor do bônus
é:
"
+
bonus) ;
{
System. out .println ( "Ocorreu
um
erro durante a
leitura ! " ) ; 21.
}
22 . 23.
} )
Sobre o código: Nas linhas 6 e 7 são declaradas as variáveis necessárias para o programa. Obser ve que o salário e o bônus são variáveis do tipo real (no Java, f lo at) e o tempo é uma variável do tipo inteiro. Nas linhas I O e 12, onde se fará a leitura desses valo res, isso é observado pela conversão adequada dos valores de entrada com as funções Float . parseFloat ( ) e Intege r . parseint ( ) . Nas linhas 1 3 a 1 7 é realizada a condicional composta que fornece o resultado desejado, como no algoritmo em português estruturado. Observe a letra f no final dos valores multiplicados: essa é outra característica da linguagem Java que garante que o tipo resultante será um valor real do tipo float.
5 .6
�
E S T R U T U RAS D E S E L EÇAO E NCADEADAS
Uma estrutura de seleção encadeada é uma seqüência de testes de seleção, os quais serão executados ou não de acordo com o resultado das condições e de acordo com o encadeamento dos testes, i.sto é, um teste de seleção pode ter dois conjuntos de instruções, conforme visto na Seção "Estruturas de seleção compostas", um para resul tado verdadeiro e outro para falso; porém, esses conjuntos de instmções podem conter outros testes de seleção, que por sua vez também podem conter outros e assim por diante.
-
'
CAPITULO 5
CONSTRUÇAO D E ALGORITMOS: ESTRUTURAS DE CONTROLE
-
59
Pseudocódigo: Se
(condição_l) então Se (condição_2)
então
A
conjunto de instruções
Senão conjunto de instruções B Fim-Se Senão conjunto de instruções C Fim-se
NOTA:
No modelo acima, se a condição_ 1 resultar verdadeiro, então será realizado o teste da condição_2; se esse teste resultar verdadeiro, será realizado o conjunto de instruções A; se resultar falso, será rea lizado o conjunto de instruções B. Se o teste da condição_1 resultar falso, será realizado o conjunto de instruções C.
Fluxograma:
condição_l
condição_2
,_.v_.�
conjunto de instruções A
.F. .
conjunto de instruções C
Java: if ( )
{
i f ( )
{
} else
{
} } else {
}
F
.
conjunto de instruções B
Fim
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
60 EXEMPLO 5.6:
Faça um algoritmo que receba três valores que representarão os lados de um triângulo e serão fornecidos pelo usuálio. Verifique se os valores for mam um triângulo e classifique esse triângulo como: eqüilátero - três lados iguais; isósceles - dois lados iguais; escaleno - três lados diferentes. Lembre-se de que, para formar um triângulo: nenhum dos lados pode ser igual a zero; um lado não pode ser maior do que a soma dos outros dois.
Pseudocódigo: 1.
Algor itmo tr iangu l o
2.
Var
3. 4.
A , B , C : inteiro Inicio
5.
Ler (A, B , C)
6.
Se (A O )
7. 8.
.e.
(B O )
.e.
(C 0 } então
Se (A. o o _,
cont < 850 .v.
\lt
num
"' \ soma f-
soma
+ num cont numeros [ j + 1 ) ) { =
21.
aux
22.
numeros [ j )
23.
numeros [ j +1 ]
numero s [ j ) ; =
numeros [ j + 1 ] ; =
aux;
1 27
CAPÍTULO 8 - BUSCA E ORDENAÇÃO
24.
}
25.
}
26. 27. 28.
}
} }
Esse método descreve exatamente o mesmo que o algoritmo ExemploS . 2. A identificação do método (linha 15) utiliza o modificador publ ic, pois é interessante que esse método tenha máxima visibilidade, embora isso não seja obrigatório. O void é utilizado pois é equivalente a um procedimento, isto é, ordena um conjunto de núme ros mas, após seu processamento, nada é acrescentado à memória do sistema. O modificador static é usado para torná-lo um método sem dependências com objetos. Os elementos que se deseja ordenar são passados como um vetor de parâmetros do tipo desejado, cujo tamanho é definido pela propriedade length dos vetores em Java, usada na linha 1 6. O modificador final (equivalente a uma declaração de cons tante) apenas indica que o tamanho do vetor não será alterado durante a ordenação.
CUIDADO!
Ao se fazerem ordenações ou mesmo pesquisas em Java utilizando strings, deve-se dedicar especial atenção. String é uma classe defini da na linguagem cujos elementos possuem características especiais. As comparações entre objetos são feitas de maneira diferente das compa rações de tipos primitivos (como números inteiros).
Para comparar a ordem de duas strings, existe um método chamado compareTo ( ) ,
definido na classe String. Esse método lê o código UNICODE equivalente das duas strings e subtrai um valor do outro. O resultado é um valor numérico do tipo inteiro tal que, se for igual a zero, as duas strings serão iguais; se for menor que zero, elas estarão ordenadas de forma crescente; e, se for maior do que zero, elas estarão em ordem de crescente ou fora de ordem crescente (vide Tabela 8.2). Para ilustrar a explicação sobre ordenação pelo Método da Bolha para strings, é apresentado a seguir o código em Java cuja única diferença para o ExemploS . 2 está na condicional da linha 20. Justamente por isso, não existe a necessidade de repetirmos a representação algorítmica em pseudocódigo e fluxograma.
String l . compareTo (String2)
Resultado =0 >0
String l . compareTo (String2)
Tr i ter saida; saida = new BufferedWriter (new FileWriter ( "Agenda . txt " ,
9.
10. 11. 12 . 13.
true) ) ;
System . ou t . println ( "Digite o nome " ) ; String Nome = entrada . readLine ( ) ; System .out .println ( "Digite o endereço " ) ; String Endereço = entrada . readLine ( ) ;
Sys tem. out. println ( "Digite o telefone" ) ;
151
CAPÍTULO 9 - ACESSO A ARQUIVOS
14.
String Telefone = entrada . readLine ( ) ;
15.
regAgenda regAgl
=
new regAgenda (Nome , Endereco,
Telefone ) ; 16.
saida.write (regAgl.mostraNome ( ) + " \ t " ) ;
17. 18.
saida.write ( regAg l . mo straEnd ( ) + " \ t" ) ; saida .write ( regAg l . mo straTel ( ) + "\n" ) ;
19.
saida. flush ( ) ;
20.
saida . close ( )
21.
} catch (Exception e) {
22 .
System. out.println ( "Erro de gravacao" ) ;
23.
}
}
24. 25.
;
}
Para ler a entrada dos dados via teclado, declarou-se uma variável entrada, que é um contêiner que recebe os caracteres de entrada digitados via teclado (linhas 5 e 6). Seguindo a mesma filosofia da entrada de dados, utilizam-se classes (e objetos) de apoio definidos na linguagem Java para trabalhar o acesso e gravação de arquivos. Nas linhas 7 e 8 está a declaração da variável (objeto) que será o contêiner do arquivo. Essa declaração é muito semelhante à declaração das variáveis que receberão a entrada de dados, mas, em vez de se utilizar um objeto do tipo Inpu ts treamReader, que define uma entrada de caracteres, utiliza-se um objeto do tipo F i l eWri ter (linha 8), que define uma saída para o arquivo Agenda . txt. Um detalhe patticular deve ser observado nessa declaração: na linha 8, quando se define o nome do arquivo destinado ao armazenamento dos dados, no trecho Fi leWr i ter ( "Agenda . txt true) , tem-se, na verdade, uma chamada de um método com passagem dos parâmetros "Agenda . txt e true. O primeiro é o nome do arquivo, conforme já foi dito, e o segundo significa que o arquivo será acessado com a condição append = true, ou seja, os dados gravados serão sempre inseridos ao final do arquivo. Vale ressaltar ainda que, caso o arquivo não exista, ele será criado automaticamente. O processo de entrada dos dados é executado a pattir das instruções das linhas 9 a 14, segundo as quais os caracteres lidos a partir do teclado serão transferidos para as respectivas variáveis de armazenamento: Nome, Enderece e Telefone. Na linha 15, ocorre a chamada do método construtor da classe, regAgenda, com a respectiva passagem dos parâmetros Nome, Enderece e Telefone, instan ciando-se um novo objeto regAgl da classe regAgenda. No trecho de código ante rior (classe regAgenda), pode-se verificar a declaração do método nas linhas 6 a 9. A saída dos dados é feita por meio do código nas linhas 1 6 a 18, com a chamada dos métodos que retornam os atributos do novo objeto criado. Por exemplo, em 11
,
11
saida . write
(regAg l . mos traNome ( )
+ " \ t" ) ,
temos a chamada do método que retoma o atributo nome do objeto regAgl e a trans ferência do resultado para a saída. O atributo " \ t 11 associado ao nome indica que, após o dado, será gravado também um espaço de tabulação como separador.
1 52
LÓGICA D E PROGRAMAÇÃO E ESTRUTURAS DE DADOS
Ao final da transferência do último dado, também é passado o caractere de con trole " \n" (nova linha), utilizado como separador, indicando o final do registro. O motivo da utilização desses separadores será visto nos exemplos posteriores. Nas linhas 1 9 e 20, são chamados os métodos s a i da . f 1 u s h ( ) e sai da. close ( ) , que fazem a transferência definitiva dos dados da memória para o arquivo e o fechamento do arquivo, respectivamente. NOTA:
Pode-se perguntar por que os dados obtidos da entrada via teclado não são transferidos diretamente para o arquivo, uma vez que eles estariam disponíveis sem a necessidade de instanciar um objeto da classe
regAgenda. O motivo é a necessidade de satisfazer os princípios da orientação a objetos, segundo os quais cada novo dado ou registro é um objeto e assim deve ser tratado. Como será visto posteriormente, a manipulação dos atributos dos objetos deve seguir esses princípios, garantindo-se que alterações nesses atributos somente poderão ser fei tas mediante a chamada de métodos, que permitirão ou não as altera ções. Os atributos de um objeto definem sua estrutura, e as operações, seu comportamento. Os métodos implementam essas operações que permitem alterações nos objetos e na sua estrutura, preservando sua integridade (princípio do encapsulamento discutido no Capítulo 4).
Operação de consulta - arquivo seqüencial A operação de consulta pode ser realizada de duas maneiras: saltando manualmente de um registro para o outro: nesse caso, o usuário visualizará todos os registros até que se chegue ao registro desejado; •
•
NoTA:
saltando automaticamente para o registro desejado: nesse caso, utiliza-se uma variável que recebe a informação a ser encontrada no arquivo e, por meio de uma estrutura de repetição, é provocado o avanço pelos registros até que seja encontrado o registro desejado. Quando se trabalha com arquivos seqüenciais, em ambos os casos to dos os registros são percorridos até que se chegue ao registro desejado.
No exemplo a seguir, será utilizado o recurso de consulta automática. Para isso, será declarada a variável Buscar, que receberá o nome a ser consultado. E>tEMPLo 9.2:
Busca seqüencial
1.
Algoritmo Exemplo_9 . 2
2.
Var tipo reg_agenda
=
em arquivo.
registro
3.
Nome : caracter
4.
End:
5. 6.
Tel: caracter
caracter
Fim_registro
'
CAPITULO 9 - ACESSO A ARQUIVOS
7.
Tipo arq_agenda : arquivo seqüencial de agenda
8.
Auxiliar: reg_agenda
9.
Agenda :
arq_agenda
Buscar: caracter
10. 11.
Inicio
12.
Abrir (Agenda}
13.
Ler(Buscar}
14.
Repita Avançar (Agenda}
15. 16.
Até
17.
Se (Auxiliar. Nome = Buscar} Então
(Auxiliar .Nome = Buscar} ou (EOF (Agenda ) ) Mostrar (Auxiliar.End, Auxi liar.Tel}
18.
Senão
19.
20.
Mostrar ( "Não cadastrado " }
21.
Fim-Se
22 .
Fechar (Agenda )
23.
1 53
Fim.
Nesse exemplo, foi utilizada a variável Buscar, que recebeu o nome a ser con sultado. A estrutura de repetição Repita provoca o avanço pelos registros do arquivo até que se encontre o nome desejado ou o final do arquivo. Se tivermos sucesso na consulta, isto é, se o nome desejado for encontrado, então o programa exibirá o endere ço e o telefone.
'
1 54
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
Fluxograma: In ício
Abrir(Agenda)
Buscar
Avançar (Agenda)
.F.
Aux•l iar.nome = Buscar ou
Auxiliar.nome = Buscar .F.
"Não cadastrado"
Fechar(Agenda)
Fim
Auxiliar.end, Auxiliar.tel
'
CAPITULO 9 - ACESSO A ARQUIVOS
1 55
Java: 1.
import java. i o . * ;
2. 3. 4.
class Exemplo 9 2 { public static void main( String [ ) args) { try{
5.
BufferedReader entrada;
6.
entrada = new BufferedReader (new InputStrearnReader
7. 8. 9. 10.
( System. in) ) ; BufferedReader arqentrada; arqentrada = new BufferedReader (new FileReader ( "Agenda . tx t" ) ) ; System . o u t . println ( "Digite o nome" ) ; Str ing Nome = entrada. readLine ( ) ;
11.
StringBuffer memoria = new StringBuffer ( ) ;
12. 13. 14. 15. 16.
String linha; while ( ( linha = arqentrada . readLine ( ) ) memoria. append ( l inha + "\n" ) ;
17.
inicio = memoria. indexOf (Nome ) ;
18.
i f ( inicio ! = - 1 ) {
! = null) {
}
int inicio = - 1 ;
19. 20. 21. 22. 23. 24. 25 .
int fim = memoria. indexOf ( " \n" , inicio ) ; char [ ] destino = new char [fim - inicio ] ; memoria. getChars (inicio, fim, destino, 0 ) ; linha = " " ; for ( int i = O ; i < fim - inicio; i++ ) {
26.
System . o u t . println ( l inha) ; }else{ System.out .println ( " I tem nao encontrado" ) ;
linha += destino [ i ) ;
}
27. 28. 29.
}
30.
entrada .close ( ) ; } catch (Fi leNotFoundExc eption erro) {
31.
32. 33. 34. 35. 36. 37.
System . o u t . println ( "Arquivo nao encontrado ! " ) ;
} catch (Exception erro ) { System.out. println ( "Erro de Leitura ! " ) ; } } }
Na implementação desse exemplo, cria-se uma estrutura chamada memoria, que é uma variável de memória do tipo StringBuffer. Em Java, esse tipo de variá vel é semelhante ao tipo String, mas permite uma estrutura de trabalho mais avança da como, por exemplo, append, que adiciona um novo conteúdo ao conteúdo já exis tente, sem perda de dados.
-
'
1 56
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
A linha 1 3 define a condicional de uma estrutura de armazenamento de dados que se repetirá enquanto houver dados a serem tidos, isto é, lerá todos os dados até o fim do arquivo. Essa condicional é equivalente à determinação de EOF (end offile). A busca é feita na variável memoria, com o método indexOf, que recebe Nome como parâmetro, dado obtido pela entrada de dados via teclado na linha 1 O. Esse método retoma a posição onde se inicia o caractere pesquisado. As posições são nume radas a partir de O, significando que o teste de condição na linha 1 8 verifica se o valor atribuído inicialmente à variável inicio foi alterado. Em caso afirmativo, ou seja, se inicio é diferente de - 1 , executam-se os comandos internos do laço. Para que seja possível obter a seqüência de caracteres correspondentes ao regis tro completo, é necessário determinar o seu final. Isso é feito por meio do comando na linha 19, que busca o caractere " \n" (nova linha) imediatamente após o primeiro caractere encontrado. É importante observar que o método indexO f é chamado nova mente, porém, dessa vez, são passados dois parâmetros: " \n" e inicio, para que a nova busca ocona a partir da posição em que foi encontrado o primeiro caractere do item pesquisado. Na linha 2 1 , utiliza-se o método getChars para se obter os caracteres corres pondentes ao registro, passando-se os parâmetros inicio e fim como delimitadores. A string obtida é armazenada na própria variável l inha, que será utilizada para exibi ção dos dados (linha 26). Foram feitos dois tratamentos de erro nas linhas 3 1 e 33, para determinar proble mas quando o arquivo não for encontrado ou quando ocorrerem outros enos genéricos, respectivamente. EXEMPLo 9.3: 1.
2
.
Operação de alteração- arquivo seqüencial.
Algoritmo Exemplo_9 . 3 Var tipo reg_agenda
=
registro
3.
Nome : caracter
4.
End: caracter
5.
Tel: caracter Fim_registro
6. 7 .
Tipo arq_agenda : arquivo seqüencial de agenda
8.
Auxiliar: reg_agenda
9.
Agenda :
arq_agenda
10.
Buscar: caracter
11. 12 .
Novo_end : caracter
13 .
Novo_tel : caracter Inicio
14 .
Abrir {Agenda)
15.
Ler (Buscar)
16.
Copiar (Agenda, Auxiliar)
17 .
Enquanto (Auxiliar.Nome Buscar)
18.
Avançar (Agenda)
e (Não EOF(Agenda) ) Faça
'
1 57
CAPITULO 9 - ACESSO A ARQUIVOS 19. 20. 21.
Copiar {Agenda , Auxiliar) Fim-Enquanto Se (Auxiliar . Nome
22 .
=
Buscar) Então
Início
25 .
Mostrar (Auxi liar . End, Auxiliar.Tel) Mostrar ( "Novo endereço: " ) Ler (Novo_end) Auxi 1 iar. end � Novo_end
26.
Mostrar ( "Novo telefone: " ) Ler (Novo tel)
27.
Auxiliar .tel � Novo_tel
28.
Armazenar (Agenda , Auxiliar)
23 . 24 .
Fim
29.
32.
Senão Mostrar ( "Não cadastrado" ) Fim Se
33.
Fechar (Agenda)
30. 31.
34.
-
Fim.
No Algoritmo 9.3 é feita uma consulta similar à do Algoritmo 9.2. Se o registro for encontrado, é recomendado que seja exibido antes da alteração. Para a alteração, devem-se declarar as vari�íveis que receberão os novos valores, preencher os novos va lores e depois atribuir esses valores às variáveis de registro: Mostrar ( "Novo endereço : Auxi liar . end
�
Novo_end
" ) ; Ler {Novo_end)
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
1 58
Fluxograma: Início
Auxiliar.nome = Busca
Abrir(Agenda)
.F.
"Não cadastrado"
Novo_tel
.V. Auxiliar.end, Auxiliar.tel
Buscar
Copiar (Agenda, Auxiliar)
Auxiliar.nome Buscar e Não EOF(Agenda)
"Novo endereço: "
Armazenar (Agenda, Auxiliar)
Novo_end >-�A
.V.
C>. o
Auxiliar.tel f Novo_tel
Fechar(Agenda) Auxiliar.end f Novo_end
3
Avance (Agenda)
Fim
"Novo telefone" Copie(Agenda, Auxiliar)
Java: 1.
public class regAgenda {
2.
private String nome ;
3.
private String end;
4.
private String tel;
S. 6.
7. 8.
public regAgenda (String nom, String ender, String telef ) { nome = nom; end - ender; tel telef;
9. 10.
=
} public String mostraNome ( ) {
11. 12 . 13.
return nome ; }
'
CAPITULO 9 - ACESSO A ARQUIVOS
1 59
pub1ic String mostraEnd ( ) {
14. 15.
return end;
16.
}
17.
public String mostraTel ( ) {
return tel;
18.
)
19. 21.
public void al teraEnd ( Str ing novoEnd) { end = novoEnd;
22.
)
23.
public void alteraTel
20.
tel = novoTel;
24. 25. 26.
( String novoTel ) {
)
)
A classe regAgenda sofreu alterações para suportar as novas necessidades do algoritmo. Foram incluídos os métodos al teraEnd e al teraTel (linhas 20 a 25) para que os objetos permitam alterações no endereço e no número do telefone. Assim, para que seja possível a alteração desses atributos, é necessário invocar (ou chamar) esses métodos, como será feito no trecho de código a seguir. 1. 2. 3.
4. 5.
import java. i o . * ; class Exemplo 9 3 { static StringBuffer memoria = new StringBuffer ( ) ; public static void main ( String [ ) args ) { try{
6.
BufferedReader entrada;
7.
entrada = new BufferedReader (new InputStreamReader ( System. in) ) ;
8. 9. 10.
BufferedReader arqentrada; arqentrada = new BufferedReader (new FileReader ( "Agenda . tx t " ) ) ; System . o u t . println ( "Digite o nome" ) ;
11.
String Nome = entrada. readLine ( ) ;
12 .
String Endereco = " " ;
13.
S tring Telefone = " " ;
14. 16.
String linha = " " ; while ( ( linha = arqentrada . readLine ( ) ) memoria. append ( l inha + "\n" ) ;
17.
}
18.
int inicio = - 1 ;
19.
inicio = memoria. indexOf (Nome ) ;
20.
if ( inic io ! = -1) {
15.
! = nulll {
24.
int ultimo = memoria. indexOf ( " \ t " , inicio ) ; Nome = Ler (inicio, ultimo ) ; int primeiro = ul timo + 1 ; ultimo = memoria. indexOf ( " \ t " , primeiro) ;
25.
Enderece = Ler (primeiro, ultimo) ;
21. 22. 23.
-
'
1 60
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
26.
primeiro
27 .
int fim = memoria. indexOf
28.
Telefone = Ler (primeiro, fim) ;
29.
regAgenda regAgl = new regAgenda (Nome, Enderece,
=
ultimo + 1 ; ( " \n" , primeiro) ;
Telefone ) ; 30.
System . o u t . println ( "Enderece: " + regAg l . mostraEnd ( ) +
31.
"Telefone : " + regAgl .mostraTel
()) ;
32 .
System. out. println ( "Entre com novo enderece" ) ;
33.
Enderece = entrada. readLine ( ) ;
34.
regAg l . a l teraEnd (Enderece ) ;
35. 37 .
System . o u t . println ( "Entre com novo telefone" ) ; Telefone = entrada. readLine ( ) ; regAgl.alteraTel (Telefone ) ;
38.
memoria. replace (inicio,
36.
fim, regAgl.mos traNome ( ) +
"\t" + regAgl .mostraEnd ( ) + " \ t " + regAgl.mostraTel
39. 40.
gravar ( ) ;
41.
arqentrada. close ( ) ;
}else{ System . o u t . println ( " Item nao encontrado" ) ;
42. 43 . 44 .
} arqentrada .close ( )
45.
} catch (Fi leNotFoundException erro ) {
46.
System.out .println ( "Arquivo nao encontrado ! " ) ;
47.
} catch (Exception erro ) { System . ou t . println ( "Erro de Leitura ! " ) ; }
48. 49. 50. 51. 52 .
;
} public static String ler (int primeiro,
53.
String dados = " " ;
54.
char ( ]
55.
memoria. ge tChar s
int ultimo ) {
destino = new char [ultimo - primeiro] ;
(primeiro, ultimo, destino, 0 ) ; O ; i < destino. length; i++) { for (int i dados += destino [ i ] ; =
56. 57 . 58.
} return dados;
59. 60.
}
61.
public static void gravar ( ) { try{ BufferedWriter saída; s aida new Bufferedlr-Jri ter (new Filelr-Jri ter
62. 63 . 64.
=
( "Agenda . txt " ) ) ; 65. 66. 67. 68. 69.
saida . write (memoria. toString ( ) ) ; saida. flush ( ) ; saida .close ( ) ; } catch (Exception erro) { System . out . pri ntln ( "Erro de gravacao ! " ) ;
());
CAPÍTULO 9 - ACESSO A ARQUIVOS 7o .
71. 72.
161
} } }
ATENÇÃO!
Observe que, para a execução do programa do Exemplo 9.3, o arquivo Agenda . txt dever numero nos)
54.
{ultimo.prox = novoNo ;
55.
ultimo = novoNo;
56.
}
57 .
IntNoSimples buscaNo (int buscaValor ) {
} } }
58.
int i = O ;
59.
IntNoSimples temp_no = primeiro;
60.
while ( temp_no
! = null)
{ i f (temp_n o . valor == buscaValor)
61.
{System . o u t . println("No
62 . posição
return temp_no;
64.
}
65.
i+ +;
66.
temp_no - temp_no.prox;
}
68.
return nul l ;
69.
}
70.
void excluiNo ( int valor)
71. 72.
+ temp_no . valor + "
+ i);
"
63 .
67 .
"
{ IntNoSimples temp_no - primeiro; while ( temp_no
73 .
! = null && temp_no .valor ! = valor)
{temp_no = temp_no .prox;
74 .
}
75.
temp_no . prox = temp_no . prox.prox;
76.
if (ultimo == temp_no .prox)
'
A
CAPITULO 10- ESTRUTURAS D E DADOS DINAMICAS
19 7
ult imo = temp_no;
77. 78.
}
79.
void exibeLista ( )
80.
. {IntNoSimples temp_no - pr1.me1.ro;
81.
int i
82.
while ( t emp_no
.
83.
=
O; ! = null)
{System . out.println( "Valor " + temp_no.valor + " posição " + i ) ;
84.
temp_no
85.
i++;
86 .
=
temp_no .prox;
} } }
Alguns dos métodos apresentados no exemplo ListaSimples102 não foram escritos no algoritmo ExemploListaSimples, por isso vamos discutir cada um dos métodos do exemplo ListaSimples102: •
insereNo_fim- esse método deve receber como parâmetro o valor que
será incluído no final da lista; nesse caso esse valor está sendo representado pela variável novoNo do tipo IntNoSimples (linha 7). Observe que o valor de prox do novoNo deverá ser nulo e se a lista estiver vazia o primeiro elemento irá receber o novoNo. Se o último elemento for diferente de nulo, o prox (apontador) do último nó deverá fazer referência ao novoNo e então o valor do novoNo deverá ser armazenado na variável ultimo. O método insereNo_fim não retoma nenhum valor, por isso é do tipo void. •
insereNo_inicio - esse método deve receber como parâmetro o valor
que será incluído no início da lista; nesse caso esse valor está sendo represen tado pela variável novoNo do tipo IntNoSimples (linha 15). Deve-se verificar se já existe algum nó na lista, isto é, se a variável que representa o primeiro nó contém valores; se isso for verdadeiro, o prox do novoNo de verá fazer referência ao primeiro nó (linha 17) e armazenar na variável pri meiro o valor do novoNo; caso contrário deverá ser verificado se o primei ro é nulo, isto é, se a lista estiver vazia, então as variáveis primeiro e ultimo receberão o valor do novoNo. O método inserNo_inicio não retoma nenhum valor, por isso é do tipo void. I...:EMBRE·sE:
Quando a lista está vazia ou contém apenas um nó o valor das variá veis que representam o primeiro e
•
o
tíltimo nós são iguais!
ContarNos - esse método não recebe nenhum parâmetro, mas deve retor
nar um valor do tipo inteiro (linha 24). É utilizado para verificar a quantidade de nós que a lista contém.
-
'
198
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
•
insereNo_posicao - esse método recebe dois parâmetros, um para
novoNo do tipo IntNoSimples e outro para posicao, que é do tipo inteiro. A variável posicao representa a posição em que o nó deverá ser
inserido no conjunto. Para determiná-la devemos verificar a quantidade de nós da lista com o método ContarNos ( ) e então, se ela não for a primeira posição da lista, varrer a lista à procura da posição desejada (linha 45). Para isso é utilizado um nó auxiliar chamado temp_no. Cada vez que um nó é lido, deve-se indicar a leitura do próximo, então temp_no deverá receber o valor de t emp_no . prox (linha 46), que traz a referência ao próximo nó e conseqüentemente o seu valor. No caso de a posição desejada ser maior do que o número de nós, o novoNo será inserido como último nó da lista (linha 53). Em todos os casos deverá ser feito o posicionamento do novoNo no conjunto e para isso, devem-se alterar as referências. Veja como exemplo novoNo . prox temp_no. prox; temp_no. prox novoNo (linhas 49 e 50). =
=
Vamos seguir o mesmo exemplo apresentado no algoritmo do Exemplo I 0.6: insereNo_po sicao ( 2, 1) - o valor 2 deverá ser inserido na posição I da lista. O valor 2 estará representado pelo novoNo e o valor 1 , pela variável posicao, então temos o esquema mostrado na Figura 10.10. Quando o nó que ocupa a posição desejada (1) for encontrado, o laço de repetição será encerrado (linhas 45 a 48), então o valor que estará armazena do em temp_no será o valor do nó que ocupa a posição anterior à desejada e o temp_no. prox conterá a referência ao nó que está na posição desejada. Após o encerramento do teste de repetição é feita a alteração das referências dos nós para que o novoNo possa ser inserido: •
novoNo . prox
novoNo.prox
=
=
temp_no. prox; em nosso exemplo temos:
a referência para o nó com valor 3;
..... . -....- . ..... . ..-· nó que ocup à\ \.a.-..posição 1. / . . .. . ..-... 1
3
5
7
nulo
próximo
próximo
próximo
próximo
1
2
3
5
7
próximo
próximo
próximo
próximo
prOXImO •
•
1FIGURA 10.1 oi Inserção de um nó em uma posição específica na lista (simples)
nulo
CAPÍTULO 10- ESTRUTURAS D E DADOS DIN Â MICAS
•
temp_no . prox
=
19 9
novoNo, com isso o nó de valor 1 (que ocupa a
posição 0) fará referência para o novoNo e este fará referência para o nó com valor 3. •
buscaNo - esse método recebe como parâmetro um valor inteiro para a
variável buscaValor. Nós utilizamos a variável temp_no (novamente!) para nos auxiliar na localização do nó, para isso é feita a varredura de todos os nós da lista por meio de uma estrutura de repetição (linha 57) que compara temp_no . valor com a buscaValor e, quando encontra o nó, retoma o temp_no, caso contrário retoma nulo. •
excluiNo - esse método recebe como parâmetro um valor inteiro para a
variável valor, que será o valor do nó a ser excluído. Nesse caso também utilizamos o temp_no e uma estnttura de repetição para percorrer a lista enquanto o valor não for igual ao temp_no . v a l o r ou enquanto o temp_no . prox não for nulo. Quando o nó é encontrado, então é necessá rio que se deixe de fazer referência a ele, o que é feito na linha 75, onde o temp_no . prox recebe o valor do próximo elemento do próximo. O método excluiNo não retoma valores. •
exibeL i sta - esse método não recebe parâmetros e também não retoma
valores. Ele exibe os nós da lista e, para isso, é utilizada a estrutura de repeti ção, que irá repetir o bloco para exibir o nó, enquanto não for encontrado nenhum nó nulo.
EXEM�Lo 1 o.a:
Com programa Exemplo102 poderemos utilizartodos os métodos da clas se ListaSimples102.
1.
import java . i o. *;
2.
class Exemplo102
3.
{
/* Constrói um menu de opções para manipulação da lista*/ public static void escolhas
()
{
4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
}
14.
public static void m a i n ( String args [ ] ) {
15.
ListaSimples102 Slist = new ListaSimples102 ( ) ;
16 .
BufferedReader entrada ;
17 .
-
'
200
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
entrada = new BufferedReader (new InputStreamReader (System. in) ) ;
18.
int i = O ;
19.
IntNoSimples temp_no;
20.
int valor;
21 .
try (
22 .
escolhas ( ) ;
23 .
char opcao = entrada . readL ine ( ) . charAt ( O ) ;
24.
while (opcao
! = '7')
25.
switch (opcao}
26 .
case
27 .
'1'
(
{
:
System .out .print l n ( "Inserir um Nó no inicio da lista " ) ;
28.
System. out . println( "Digite um valor" ) ;
29.
valor = Integer .parseint ( entrada . readL ine ( ) ) ;
30.
Slist. insereNo_ini c i o ( new IntNoSimples (valor ) ) ;
31.
break;
32 .
case '2'
33.
:
System . o u t . println("Inserir um Valor no final da lista " ) ;
34.
System . o u t . println("Digite um valor " ) ;
35.
valor = Integer .parseint ( entrada . readL ine ( ) ) ;
36.
S l i s t . insereNo fim(new IntNoSimples(valor} ) ;
37 .
brea k; case
38. 39.
'3'
:
System . out . println("Inserir um Valor numa dada posicao" J ;
40.
System . o u t . println("Digite um valor" ) ;
41.
valor = Integer .parseint ( entrada . readL ine ( ) ) ;
42 .
System . ou t . println("Digite a posicao" ) ;
43 .
int posicao = Integer .parsein t ( entrada . readLine( ) ) ;
44 .
Slist. insereNo_posicao ( new IntNoSimples(valor) ,posicao) ;
45. 46 .
break; case
'4':
47 .
System . out . println( "Localiza um valor" ) ;
48.
System . o u t . println( "Digite um va lor" ) ;
49.
valor = Integer .parseint ( entrada . readLine ( ) ) ;
50.
Slist .buscaNo(va l or ) ;
51 .
break;
52 .
case
'5' :
53 .
System . o u t . println ( "Exclui um elemento da lista " ) ;
54.
System .out .println ("Digite o valor" ) ;
55.
valor = Intege r . parseint ( entrada . readLine ( ) ) ;
56 .
S l i s t . excluiNo(valor ) ;
57 .
break;
58. 59.
case
'6 ' :
System . ou t . p rintln( "Exibe a lista " ) ;
CAPÍTULO 10- ESTRUTURAS D E DADOS DIN Â MICAS
60.
S l i s t . exibeLista( ) ;
61.
break;
62.
default
63. 64.
} System .out. println ( ) ;
65.
escolhas ( ) ;
66 .
opcao = entrada . readLine () . charAt ( O ) ;
67.
:
System .out. println
201
( " Opcao Inva lida ! " ) ;
}
}
68.
catch
69.
(Exception erro ) {
System. out . println ( "Erro de Entrada de Dados" ) ;
}}}
70.
1 0 .3 LISTAS DUPLAMENTE E N CADEADAS
Quando se percorre uma lista de encadeamento simples é bastante difícil fazer o caminho inverso, já nas listas de encadeamento duplo esse problema não existe, pois cada nó possui uma referência para o próximo elemento da lista e outra para o anterior. A concepção de uma lista duplamente encadeada é bastante similar à dos sim ples, basta acrescentar ao nó uma variável que fará referência ao elemento anterior, da mesma maneira que é feito com o próximo. Veja na linha 6 do ExemploLis taDupla:
ExEMPLo 10.9:
Pseudocódigo para representar uma lista duplamente encadeada.
1.
Algoritmo ExemploListaDupla
2.
Tipo apontador:
3.
ANoDuplo
NoDuplo = registro
4.
va lor:
5.
prox: apontador
6.
ant:
7. 8.
inteiro
apontador
fim ListaDupla = registro primei ro : apontador
9. 10.
ultimo:
11.
numero_nos:
12. 13 .
apontador inteiro
fim Inicio
14.
ListaDupla. numero_nos � O
15.
ListaDupla. primeiro �nulo
16 .
ListaDupla. ultimo �nulo
Para escrevermos algoritmos de manipulação de lista duplamente encadeada po demos seguir o mesmo raciocínio adotado para o entendimento da lista de encadeamen to simples, mas devemos lembrar que o nó anterior também precisa ser referenciado a cada manipulação.
-
'
202
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
No algoritmo a seguir, que é continuação do ExemploLis taDupla, demons traremos os procedimentos para inserir um nó no final da lista e para excluir um nó de acordo com a sua posição. Nesta solução para exclusão de nó é necessário descobrir qual é o nó que ocupa a posição desejada para a exclusão; para isso, utilizaremos a função pegarNo ( } . Essa função recebe como parâmetro o índice do nó a ser excluído e retoma o próprio nó. .
17 . 18.
.
Procedimento InsereNo_fim {var novoNo: NoDuplo) inicio
19.
NovoNo A . prox
nulo
20.
NovoNo A . ant
21 .
if(ListaDupla . primeiro
22.
ListaDup l a . primeiro
f-
u ltim o
t-
nulo)
=
f-
novoNo
23.
fim-se
24.
i f {ListaDupla.ultim o < > nulo)
25.
ListaDupla . u l t imoA . prox
26.
fim-se
27 .
L is taDup la . u ltim o
t-
f-
novoNo
novoNo
28.
ListaDupla . numero_nos f- ListaDupla.numero_nos + 1
29.
fim
30.
Procedimento pegarNo {var indice:
31.
var
32 .
temp_no: NoDuplo
33. 34.
i:
inteiro) : NoDuplo
inteiro
J.nl.Cl.O .
35.
temp_no
36.
Enquanto ( t emp no
f-
ListaDup l a . primeiro _
37 .
temp_no
38.
i t- i + l
f-
<
>
nulo && i
<
- indice)
temp_noA. prox
39.
f im_enquanto
40.
Return temp_no
41.
fim
42.
Procedimento InsereNo_posic a o ( novoNo: NoDupl o ,
43.
var
44 . 45.
temp_no : NoDuplo inicio
46.
temp_no
47.
novoNoA.prox
48.
Se
f-
pegarNo (indice) f-
temp_no
( temp_noA . prox < > nulo)
então
49.
novoNo". ant f- temp_noA. ant
50.
novoNo". proxA. ant f- novoNo
51.
Senão
52 .
novoNo A . ant f- novoNo
53.
ListaDupla .ultimo
54.
fim-se
55.
Se
56.
{ í ndic e = 0 )
f-
novoNo
então
ListaDup l a . primeiro f- novoNo
índice: inteiro)
'
A
CAPITULO 10- ESTRUTURAS D E DADOS DINAMICAS
57.
203
Senão novoNoAan t A . prox f- novoNo
58. 59.
fim-se
60.
ListaDupla.numero_nos
f-
L i staDupla . numero_nos + 1
61 .
fim
62.
Procedimento excluiNo ( i ndice: inteiro)
63.
var
64.
temp_n o : NoDuplo
65.
l.nl.Cl.O
66 .
Se
( indice
=
0)
então
67.
L istaDupla . primeiro f- ListaDupla . primeiroA.prox
68.
Se (Li staDupla. primeiro < > nulo) então ListaDupla. primeiroA .ant f- nulo
69.
fim-se
70. 71.
Senão
72.
Se
(temp_n o < > ult imo}
f-
73.
temp_no
74.
temp_n o A . a n t A . prox
pegarNo(indice)
f-
temp_n o A . a n t
Senão
75.
ListaDup l a . u ltimo f- temp_no
76 .
fim-se
77. 78.
fim-se
79.
L i s taDupla.numero_nos
f-
Lis taDupla . numero_nos
-
1
fim
80. 81.
então
fim.
seguir será apresentada a implementação da lista duplamente encadeada em Java. Observe que na classe IntNoDuplo, é criada a estrutura do nó, assim como fizemos para a lista simples, apenas acrescentamos o campo de referência ant que irá fazer referência ao nó anterior. A
EXEMPLO 10.1o: Classe que cria um 1.
nó duplo.
class IntNoDuplo(
2.
int valor;
3.
IntNoDuplo prox;
4.
IntNoDuplo a n t ;
5. 6.
In tNoDuplo ( i n t ValorNo) (
7.
valor = ValorNo;
8.
prox
ant = null;
}
9. 10.
=
}
ExEMPLO 1 o. 1 1: Implementação dos mesmos métodos utilizados no algoritmo ExemploListaDupla.
1.
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
204
class ListaDuplal04(
2.
IntNoDuplo primeiro, ultimo;
3.
int numero_nos;
4. 5.
ListaDuplal04
()(
6.
primeiro = ultimo - null;
7.
numero_nos = O ;
8.
}
9. 10.
void insereNo
(IntNoDuplo novoNo ) { null;
11.
novoNo . prox
12.
novoNo . ant = ultimo;
13 .
if
=
(primeiro == null) primeiro = novoNo;
14. 15.
if
16.
(ultimo ! = null) ultimo . prox = novoNo;
17.
ultimo = novoNo;
18.
numero_nos++;
19.
}
20.
IntNoDuplo pegarNo
(int indice ) (
21.
IntNoDuplo temp_no = primeiro;
22 .
for
23 .
(int i = O ;
( i < indice)
&&
( t emp_no
temp_no = temp_no .prox;
24.
r e turn temp_no;
25.
}
26.
void incluiNo
(IntNoDuplo novoNo,
int indice ) {
27 .
IntNoDuplo temp_no = pegarNo ( indice ) ;
28.
novoNo . prox = temp_no;
29.
if
(novoNo .prox != nul l ) {
30.
novoNo . ant = temp_no .ant;
31.
novoNo .prox.ant = novoNo; } else {
32. 33 .
novoNo . ant = ultimo;
34.
ultimo
35.
}
36.
if
37. 38.
=
novoNo;
( indice == O ) . . pr�me�ro = novoNo;
else
39.
novoNo .ant.prox = novoNo; numero_nos++;
40. 41.
}
42 .
void excluiNo (int indice) {
43.
if
(indice
==
0){
44.
pr1me1ro = pr1me1 r o . prox;
45.
if
o
48.
o
•
o
(primeiro ! = null) primeiro .ant = null;
46. 47 .
! = null ) ;
} else( IntNoD uplo temp_no
=
pegarNo
(indice ) ;
i++)
'
A
205
CAPITULO 10- ESTRUTURAS D E DADOS DINAMICAS
49.
temp_no .ant.prox
50.
if ( temp_no
temp_no .prox;
! = ultimo)
temp_no .prox.ant
51.
=
temp_no . a n t ;
else
52. 53.
ultimo
54.
}
55.
numero_nos- ;
56. 57.
=
=
temp_no ;
} } 1 o. t 2: Este programa utiliza as classes criadas no Exemplo 10.11.
1.
class Exemplol 04{
2.
public static void main ( String [l
args) {
3.
ListaDuplal04 Slist - new ListaDuplal04
4.
Slist. insereNo (new IntNoDuplo ( 1 ) ) ;
5.
S1ist. insereNo (new IntNoDuplo ( 3 ) ) ;
6.
S l i s t . insereNo (new IntNoDuplo ( 5 ) ) ;
7.
S l i s t . insereNo (new IntNoDuplo
8.
IntNoDuplo temp_no = Slist. primeiro;
9.
while (temp_no
();
{7) ) ;
! = null) {
10.
System . o u t . println
11.
temp_no = temp_no .prox;
( t emp_no .valor ) ;
12.
}
13 .
Slist. incluiNo (new IntNoDuplo
14.
System .out.println ( "Apos incluir o no 2 . . . " ) ;
15.
temp_no = S l i s t . primeiro;
16.
while (temp_no
{2) ,
1) ;
! = null) (
17.
System . o u t . println
18.
temp_no = temp_no .prox;
( t emp_no .valor ) ;
19.
}
20.
Slist. excluiNo ( 2 ) ;
21.
System .out.println ( "Apos excluir o no 3 . . . " ) ;
22.
temp_no = S l i s t . primeiro;
23 .
while (temp_no
! = null) (
24.
System . o u t . println
25 .
temp_no
temp_no . prox;
}
26. 27. 28 .
=
( temp_no .valor ) ;
} }
1 0 .4 FILAS
Acho que todos nós já ficamos em uma ftla. Fila para comprar ingressos para shows, pegar dinheiro no banco e, às vezes, até para comprar o pãozinho da manhã. O conceito de fila em programação é o mesmo dessas filas em que esperamos para ser atendidos em ordem: o primeiro elemento a entrar na fila será o primeiro elemento a
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
206
sair. Esse conceito é conhecido como 'First In, First Out' ou FIFO, expressão conhecida em pottuguês como PEPS ou 'Primeiro Que Entra, Primeiro Que Sai'. Então, no concei to de fila, os elementos são atendidos, ou utilizados, seqüencialmente na ordem em que são armazenados. As filas (queues) são conjuntos de elementos (ou listas) cujas operações de in serção são feitas por uma extremidade e de remoção, por outra extremidade. Como exemplo pode-se implementar uma fila de impressão, em que os arquivos a ser impressos são organizados em uma lista e serão impressos na ordem de chegada, à medida que a impressora estiver disponível. Seqüência armazenada em fila
li
li
r
r
Novos elementos
O primeiro elemento a
são armazenados
entrar será o primeiro
no fim da fila
elemento a sair (FIFO)
I FIGURA
1 o. 1 1 I Conceito de fila
Conforme comentamos na introdução de listas, a implementação das listas, filas, pilhas e árvores pode ser feita por meio de arranjos ou de ponteiros. Até agora fizemos as implementações utilizando ponteiros, então iremos exemplificar a implementação de filas e pilhas por meio de arranjos, uma vez que o exemplo pode ser facilmente adaptado para o uso de ponteiros. LEMBRE -sE:
Ao implementarmos a fila por meio de arranjos, estaremos utilizando um vetor como contêiner para o armazenamento dos elementos que estarão na fila.
Para definir a estrutura de uma fila, implementada por arranjo, é necessário cons truir um registro que contenha as informações da fila, como o início, o final e o contêiner de elementos, que é um vetor; nesse caso cada um dos elementos da fila será represen tado por uma posição no vetor. Veja a estrutura: ExEMPLO 10.13: Pseudocódigo que representa uma fila implementada com arranjo. 1.
Algoritmo Fila
2.
var
'
A
CAPITULO 10- ESTRUTURAS D E DADOS DINAMICAS
207
Tipo fila_reg - registro
3. 4.
inicio:
5.
fim:
6.
elemento : vetor [ 1
7.
inteiro
inteiro .
.
50]
de inteiro
fim total:
8.
inteiro
fila: . l.nl.Cl.O
9.
.
10.
fila_reg
.
f- O fila. fim f- O total f- O
11.
fila. inicio
12. 13.
Observe que a variável elemento, que é do tipo vetor, comporta 50 números inteiros. Essa característica é um limitador para trabalharmos com arranjos, pois pode remos inserir apenas 50 valores! Para implementar uma fila com o uso de ponteiros (alocação dinâmi
NOTA:
ca), basta utilizar o nó e fazer as manipulações de acordo com o con ceito PEPS.
Algoritmo que representa uma fila implementada com arranjo 14.
Função vazia (
15.
l.nl.Cl.O
16.
Se ( total
17. 18.
21. 22. 23. 24.
29. 30.
31. 32.
entao
return . f . fim-se fim Função cheia (
) :
lógica
J.nl.Cl.O Se ( total >= 5 0 )
então
return . v . Senão
27. 28.
0)
Senão
25. 26.
=
lógica
return . v .
19. 20.
) :
return . f . fim-se fim Procedimento enfileirar (elem:
inteiro)
inicio Se
(cheia( )
= . f . . ) então
33.
f i l a . elemento [inicio] � elem
34.
f i l a . fim
35 .
total f- total + 1
36.
Se
37.
38.
f-
fila. fim + 1
( f i l a . fim >= 5 0 ) fila. fim = O
fim-se
então
39.
Senão
40.
Mostre ( "Fila cheia ! " )
41. 42. 43. 44.
fim-se fim Funcao desenfileirar(
)
inte i ro
:
var
45. 46.
-
'
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS
208
excluido: inteiro l.nl.Cl.O Se (vazia( )
47 .
=
48.
excluido
49.
fila. inicio
50.
Se
51.
f-
.f.)
então
f i l a . element o [ inicio)
f-
fila. inicio + 1
( fi la . in i cio
>
fim- se
53 .
total f- total - 1
54.
Senão
55.
excluido f- nulo
56.
retorne excluido
57.
fim-se
59. 60.
var i:
inteiro
l.nl.Cl.O Para ( i f- O até total)
64 .
Mostre ( " Posição " ,
65.
67 .
retorne excluido
Procedimento exibeF i l a ( )
63 .
66.
então
fim
61. 62 .
tamanho )
f i l a . inicio f- O
52 .
58.
=
faça
i1
" valor "
elemento [ i ) )
fim-para
fim fim.
A seguir será apresentado o programa escrito em Java para representar esse algo ritmo, então faremos as explicações do código, assim evitaremos a repetição das expli cações, que são similares para o código e para o algoritmo! Java: classe que representa uma fila implementada com arranjo 1.
class Fila {
2.
int tamanho;
3.
int inicio;
4.
int fim;
5.
int total;
6.
Object vetor [ ) ;
7.
Fila ( int tam)
{
8.
inicio = O ;
9.
fim = O ;
10.
total = O ;
11.
tamanho
=
tam;
'
A
CAPITULO 10- ESTRUTURAS D E DADOS DINAMICAS vetor = new Object [ tam] ;
12. 13 .
}
14.
public boo1ean vaz1a ( )
15.
if
16.
( total
{
0)
==
return true; else
17.
return false;
18. 19.
}
20.
public boo1ean cheia ( ) if
21. 22.
( total
>=
{
tamanho)
return true;
23 .
else
24.
return false;
25.
}
26.
pub1ic void enfi1eirar(Object elem) if
27. 28.
{
( ! cheia ( ) ) { vetor [ f i m ]
e1em;
=
29.
fim++;
30.
total++;
31.
i f (fim >= tamanho) fim =
32. 33.
}
34.
else
O;
{ System.out .println ( "Fila Cheia" ) ;
35. 36.
}
37.
}
38.
public Object desenfileirar ( )
39.
{ Object excluido;
40.
{ if
(vazia ( ) == fa1se)
41.
{exc1uido = vetor [inicio ] ;
42. 43 .
inicio++; if
( inicio
>=
tamanho )
inicio = O ;
44. 45.
total -;
46.
return excluido;
} e1se
47. 48.
{ excluido = nu11;
49.
return excluido;
50.
}
51.
}
52.
}
53.
public void exibeFil a ( )
54.
{for (int i
=
O ; i < total; i++)
{System . o u t . p rintln("posicao " + i + " valor
55.
vetor [ i l l ;
56. 57. 58.
209
}
}
}
"
+
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS '
210
Para representarmos uma fila em Java criamos a classe Fila, que contém as variáveis para tamanho da fila, início e fim da fila, total de elementos da fila e o vetor para armazenamento dos elementos, linhas 1 a 6. Observe que o vetor irá armazenar elementos do tipo objeto; nesse caso, podem ser armazenados quaisquer tipos de valo res e essa fila pode ser considerada uma fila genérica. Observe também que o tamanho do vetor é passado como parâmetro para o método construtor, linha 7. Vamos discutir cada um dos métodos que foram apresentados no programa F i la: vazia ( ) e cheia ( ) - linhas 14 e 22, não recebem nenhum parâmetro e
•
retornam um valor lógico. Esses métodos são utilizados para verificar se a fila está vazia ou cheia. A verificação é feita comparando-se a variável total com O ou com a quantidade de elementos que o vetor compo1ta, no caso do exemplo apresentado para vazia (linha 16) Se o total for igual a O, significa que a fila está vazia e o método retornará verdadeiro, caso contrário retornará falso. Já para verificarmos se a fila está cheia, na linha 24 o teste feito compara o total com a quantidade de elementos que o vetor comporta (tamanho), então se isso for verdadeiro significa que a fila está cheia e o retorno é verdade iro, caso contrário o retorno é falso. Essas funções serão utilizadas nas chamadas aos métodos para enfileirar ou desenfileirar elementos. Elas são importantes para que seja verificado se es sas operações serão ou não possíveis de ser realizadas. enfileirar -linha 26, recebe como parâmetro um valor do tipo Obj ect
•
para a variável elem e não retoma nenhum valor, por isso é do tipo void. Na linha 27 é feita uma chamada ao método cheia para verificar se é possí vel a inserção de um novo elemento na fila. A expressão ! cheia ( ) é simi lar a cheia ( ) ==false. O elemento deve ser inserido no final da fila, a fim de que seja respeitado o conceito PEPS, então o último elemento do vetor deverá ser o elemento que está sendo inserido: vetor [ f im] =elem (linha 28). As variáveis fim e total devem ser incrementadas, então é verificado se a variável fim é maior ou igual a tamanho, para garantir que a fila con tenha a quantidade de elementos que podem ser comportados pelo vetor esse recurso força a circularidade da fila. Veja o esquema a seguir: Suponha que a fila tenha capacidade para cinco elementos do tipo inteiro: pos•çao
o
1
2
3
4
valor
45
7
9
32
1
.
-
organização
primeiro elemento I FIGURA
último elemento
1 o. 1 2 1 Representação de uma fila
Se retirarmos um elemento, o elemento a ser retirado será o que está em pri meiro lugar na fila, no caso ele ocupa a posição O e seu valor é 45. Com a retirada do elemento a fila ficará da seguinte maneira:
CAPITULO 1 0 - ESTRUTURAS DE DADOS DINAMICAS '
21 1
A
posição
1
2
3
4
valor
7
9
32
1
organização
primeiro elemento
último elemento
Início
Fim
I FIGURA 1 o. 1 3 1 Represenlação da fila após a remoção de um elemento
O elemento que passou a ser o primeiro da fila ocupa a posição 1 no vetor e o seu valor é 7. Observe que ainda cabe um elemento. Conforme os elementos vão sendo retirados da fila, o início da fila deve ser incrementado, de maneira que o primeiro elemento do conjunto a entrar na fila seja sempre o primeiro a sa11·. o
Quando o tamanho da fila, que determina o número de posições que o vetor pode conter, estiver completo, se existirem posições vazias os elementos in seridos deverão ocupar as posições 'desocupadas' que estão no início do ve tor, por isso o fim da lista é zerado (linhas 3 1 e 32), sempre respeitando a ordem imposta por PEPS. Para isso o início e o ftm devem ser incrementados. posição
1
2
3
4
o
valor
7
9
32
1
novo valor
organização
primeiro elemento
último elemento
Início
Fim
I FIGURA 1 o. t 4 l Represencaçâo do fim da fila
Quando um novo valor for inserido será armazenado na posição final da fila, e o último elemento será este! •
O,
que é o
desenf ileirar - o método desenfileirar não recebe nenhum pa
râmetro, pois o elemento a ser excluído é o elemento que está no início da fila. Esse método retoma o elemento que está sendo excluído, que é do tipo Obj ect, para isso foi declarada a variável exclui do, na linha 39. Nesse caso, se não existir nenhum valor na fila, o retorno do método será null; isso é possível pois o dado é do tipo Obj ect, que aceita nulos. oesERvAçÃo:
No algoritmo também atribuímos nulo ao retomo, somente a título de representação, pois o tipo de dado que a função retoma é inteiro, e este não aceita nulos.
Na linha 40 é feita uma chamada ao método vazia ( ) , cujo resultado será testado. A instrução vazia ( ) ==false é similar a ! vazia ( ) , então, se a fila não estiver vazia a variável excluído receberá o primeiro elemento da fila (linha 41) e o início da fila deverá ser incrementado (linha 41) e o total de elementos, decrementado (linha 45). Note que, na linha 43, se inicio for
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS '
212
maior ou igual a tamanho o valor de inicio será zerado. Assim como fizemos no método insere, com a variável fim devemos fazer isso para garantir a circularidade da flla. Veja no exemplo anterior. •
exibeFi l a - esse método não recebe nenhum parâmetro e também não
retorna nada. É utilizado para exibir os elementos da fila, o que é feito com o uso da estrutura de repetição for, que repete o processo de exibição do valor do elemento e da posição que ele ocupa até que a variável de controle i atinja o valor do total de elementos. A classe usaFila possibilita que o usuáiio selecione a opção desejada para manipulação da fila e utiliza todos os métodos que implementamos na classe Fila. Java: classe que utiliza uma fila 1.
import j ava . io . * ;
2.
class usaFila {
3.
() {
public static void escolhas
4.
System . out .print
( " Escolha a Opcao : " ) ;
S.
System . o u t . print
( "\ n l .
6.
System. out . print ( " \n2 . Excluir" ) ;
7.
System.out . print ( " \n3. Exibir a Fila" ) ;
8.
System . o u t . print ( " \n4.
9.
System . o u t . print ( " \n . Opcao
Inserir" ) ;
Sair" ) ; :\t " ) ;
10.
}
11.
public static void main(String args [ ) ) {
12.
Fila objFila
13.
BufferedReader entrada;
14.
entrada
=
=
new BufferedReader( new InputS treamReader (System. in ) ) ;
15. 16.
Object valor;
17 .
try {
18 .
escolhas ( ) ;
19.
char opcao
20.
while
21.
new Fila ( 10 ) ;
entrada . readLine ( ) . charAt ( O ) ;
=
(opcao ! = ' 4 ' )
{
switch (opcao) {
22.
case ' 1 '
23.
if
:
( ! objFila. cheia ( ) ) ( "Digite algo:
24.
{System . out . print
25.
valor
26.
objFila. enfileirar (valor ) ;
27 .
}
28.
else
=
");
entrada. readLine ( ) ;
{System. out. println ( "Fila Cheia ! " ) ;
29. 30.
}
31.
break;
32.
case ' 2 '
33.
if
:
(objFi l a . vazia ( )
false)
CAPITULO 1 0 - ESTRUTURAS D E DADOS DINAMICAS '
A
34.
213
(System . o u t . println (objFila. desenfileirar ( ) ) ;
35.
}
36.
else
{System . out . print l n ( " F i l a Va z ia !
37. 38.
}
39.
break;
40.
case ' 3 '
objFila. exibeFi l a ( ) ;
42.
break; defaul t
:
System. out. println ( "Opcao Invalida ! " ) ;
44.
}
45.
System . ou t . println ( ) ;
46.
escolhas ( ) ;
47.
opcao
48.
entrada. readLine ( ) . charAt ( O ) ;
}
49.
} catch (Exception erro ) (
50.
System . o u t . println ( "Erro de Entrada de Dados" ) ;
51. 52. 53.
=
);
:
41. 43 .
"
}
}
}
1 0 . 5 P I L HA S
As pilhas também são conhecidas como lista LIFO (Last In, First Out), que em po1tuguês significa 'último a entrar e primeiro a sair' (UEPS). E uma lista linear em que '
Novos elementos são armazenados /. no topo da pilha
O último elemento que entrou será o primeiro elemento a sair (UEPS)
Seqüência armazenada em pilha
I FIGURA 1 o. • s i Conceito de pilha
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS '
214
todas as operações de inserção e remoção são feitas por um único extremo denominado topo. Um exemplo bastante comum em que se aplica o conceito de pilhas é o de uma pilha de pratos que estão guardados no armário: quando a pessoa vai utilizar um deles pega sempre o prato que se encontra no topo da pilha, assim como, quando um novo prato vai ser guardado, é colocado no topo. Isso acontece porque apenas uma das extre midades da pilha está acessível. A operação de inserção é denominada empilhamento e a de exclusão,
desempilhamento. EXEMPLO 1 0. 1 4: Pseudocódigo que representa uma pilha implementada com arranjo.
1. 2.
Algoritmo Pilha var
3.
Tipo pilha_reg - registro
4.
topo:
5.
elemento: vetor [1 . . 5 0 ]
6.
fim
pilha: pilha_reg
7. 8. 9. 10. 11.
inicio pilha . topo � - 1 Função vazia ( . . �n�c�o Se
14 .
então
fim Função cheia ( . . �n�c�o
) :
lógica
'
Se
(pilha. topo >= 5 0 )
retorne
21.
.
v
então
.
Senão
22.
retorne . f .
23. 24.
27.
-1)
fim-se
20.
26.
=
retorne . f .
16.
25.
(pilha. topo
Senão
15.
19.
lógica
retorne . v .
13 .
18.
) :
'
12 .
17 .
inteiro
fim-se fim Procedimento empi lhar (elem: . . �n�c�o
inteiro)
'
Se (cheia ( )
28.
=
. f . ) então
29.
pilha. topo �pilha. topo + 1
30.
elemento . topo � elem
31.
Senão Mostre ( "Pilha Cheia ! " )
32 . 33. 34 . 35.
fim-se Função desempilhar (
var
) :
inteiro
de inteiros
CAPITULO 1 0 - ESTRUTURAS D E DADOS DINAMICAS '
A
36.
215
valorDesempilhado : inteiro
37.
início Se (vazia (
38.
)
=
.f.)
então
39.
Mostre ( " Pilha vazia ! " )
40.
valorDesempilhado t- nulo
41.
retorne (valorDesemp ilhado)
42.
Senão
43 .
valorDes empilhado
44.
pilha. topo
45.
retorne(valorDesempilhado)
t-
t-
pilha.vetor [ topo]
pilha. topo - 1
fim-se
46. 47.
Procedimento exibePilha(
)
var
48. 49.
.
50. 51.
i : inteiro
.
'
l.nl.Cl.O Para (i
t-
O
até topo)
Mostre( "Elemento " ,
52. 53 .
faça elemento [ i ] ,
" posição " ,
i)
Fim-para
fim
54. 55.
fim.
A definição da estrutura da pilha é bastante similar à definição de uma fila. Ob serve que na fila temos o início, o fim e o vetor; na pilha temos o topo e o vetor (linhas 3 a 7). Como na pilha as inserções e remoções são feitas por uma única extremidade, denominada topo, não é necessário que se conheça o elemento da outra extremidade; já na fila isso se faz necessário, uma vez que as inserções são feitas por uma extremidade (fim) e as remoções, por outra (início). NOTA:
Para implementar uma pilha utilizando alocação dinâmica (ponteiros), basta utilizar a estrutura do nó e fazer as manipulações de acordo com o conceito UEPS.
A seguir vamos apresentar o programa em Java para implementar uma pilha e então faremos os comentários sobre o código. Java: classe que representa uma pilha 1.
class Pilha {
2.
int tamanho;
3.
int topo;
4.
Object vetor [ ] ;
5.
Pilha (int tam)
{
6.
topo = - 1 ;
7.
tamanho = tam;
8.
vetor = ne�v Obj e c t [ tam] ;
9. 10.
} public boolean vazia ( )
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS '
216
11.
{ i f ( topo
12 .
--
-
-1)
return true;
13 .
else
14.
return false;
15.
}
16.
publ ic boolean cheia ( ) { if ( topo >= tamanho)
17 .
return true;
18. 19.
else return false;
20. 21.
}
22.
public void emp ilhar ( Object e l em )
{ i f (cheia( )
23. 24 .
== false)
{topo++;
25.
vetor[ topo]
26.
}
27.
else
28.
=
elem;
{System.out. print l n ( "Pilha Cheia" ) ;
29.
}
30.
}
31.
public Object desempilhar ( )
32 .
(Object valorDesempilhado;
33.
if
34.
(vazia( )
==
false)
{ System. out.print( "Pilha Vazia" ) ;
35.
valorDesempilhado
36.
r e tu rn val orDesemp il hado;
=
37 .
}
38.
else { valorDesempilhado
39.
nul l ;
=
vetor [topo ] ;
40.
topo-;
41.
return valorDesempilhado;
42 .
}
43 .
}
44.
public void exibePi lha ( )
45.
{for(int i = topo; i > = O ;
46.
System.out.println ( "E1emento " + vetor [ i ]
i-) +
"
pos1cao " +
i) ; 47 . 48.
}
}
No algoritmo criamos um registro para representar a pilha, no programa em Java devemos criar uma classe. Na detinição do vetor, no algoritmo, determinamos o tama nho máximo de elementos aceitos: elemento: vetor [ 1 . . 5 0 ] de inteiros. Já na classe podemos defrnir o vetor: Obj ect vetor [ ] , e no método construtor da classe passar como parâmetro o tamanho do vetor: vetor new Obj ect ( t am ) . Vamos discutir cada um dos métodos que foram apresentados no programa Fila: =
CAPITULO 1 0 - ESTRUTURAS DE DADOS DINAMICAS '
A
•
217
vazia ( ) e cheia ( ) - linhas 10 e 16, não recebem nenhum parâmetro e
retornam um valor lógico. Esses métodos são utilizados para verificar se a pilha está vazia ou cheia. A verificação é feita comparando-se a variável topo com -1 ou com a quantidade de elementos que o vetor comporta, no caso do exemplo apresentado para vazia (linhal 0) Se o topo for igual a -l, significa que a pilha está vazia e retornará verdadeiro, caso contrário retornará falso. Já para verificarmos se a pilha está cheia, na linha 16, o teste feito compara o topo com a quantidade de elementos que o vetor compOita (ta manha), então se isso for verdadeiro significa que a pilha está cheia e o retor no é verdadeiro, caso contrário o retorno é falso. Essas funções serão utilizadas nas chamadas aos métodos para empilhar ou desempilhar elementos. Elas são importantes para que seja verificado se es sas operações serão ou não possíveis de ser realizadas. •
empilhar - linha 22, recebe como parâmetro um valor do tipo Obj ect
para a variável elem e não retoma nenhum valor, por isso é do tipo void. Na linha 23 é feita uma chamada ao método cheia para verificar se é possí vel a inserção de um novo elemento na pilha. O elemento deve ser inserido no topo da pilha, a fim de que o conceito UEPS seja respeitado, então o elemento do topo deverá ser o elemento que está sendo inserido: vetor [topo ) = elem (linha 25), e a variável topo deve ser incrementada. Veja o esquema a seguir. Suponha que a pilha tenha capacidade para cinco elementos do tipo inteiro, então vamos inserir o elemento 45:
posição
valor
o
45
topo
I FIGURA 1 o. 1 61 Inserção de um elemento na pilha
Se inserirmos um novo elemento, por exemplo o número 7, a pilha ficará da seguinte maneira: .
-
postçao
valor
1
7
o
45
topo
I FIGURA 1 o. t 7 l Representaçlío da pilha após a inserção de um novo elemento
Se continuarmos as inserções até que a pilha fique cheia teremos:
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS '
218
I FIGURA
1 o. 1 8 1
posição
valor
4
1
3
32
2
9
1
7
o
45
topo
Representação da pilha completamente preenchida
Observe que o último valor que foi inserido, o número 1 , é o valor que ocupa. o topo da pilha, já o primeiro valor que foi inserido, o número 45, fica no final da pilha e, nesse caso, será o último elemento a ser retir:ado da pilha (desem pilhado).
posição
valor
4 3
32
2
9
1
7
o
45
topo
I FIGURA 1 o. 1 91 Representação da pilha após uma remoção
Observe que o elemento seguinte passou a representar o topo. IMPORTANTE!
Em nossa representação deixamos de mencionar o número 1, que esta va no topo, mas na verdade essa é uma operação lógica, e não física. A referência ao topo passa para o elemento seguinte, com isso o valor que estava no topo deixa ele ser referenciado na pilha e o seu espaço poderá ser ocupado por outro valor.
•
desempi lhar - o método desemp i lhar não recebe nenhum parâme
tro, pois o elemento a ser excluído é o elemento que está no topo da pilha. Esse método retorna o elemento que está sendo excluído, que é do tipo Obj ect, e para isso foi declarada a variável valorDesempilhado, na linha 32. Nesse caso, se não existir nenhum valor na fila o retorno do método será null, isso é possível pois o dado é do tipo Object, que aceita nulos. 0BSERVAÇÁO•l
No algoritmo também atribuímos nulo ao retomo, somente a título de representação, pois o tipo ele dado que a função retoma é inteiro, e este não aceita nulos.
CAPÍTULO 1 0 - ESTRUTURAS D E DADOS DINÂMICAS
219
Na linha 33 é feita uma chamada ao método vazia ( ) , cujo resultado será tes tado. Então, se a pilha não estiver vazia, a variável valorDesempilhado receberá o elemento do topo da pilha (linha 39) e o topo da pilha deverá ser decrementado, confor me visto no exemplo anterior. •
exibePilha - este método não recebe nenhum parâmetro e também não
retoma nada. É utilizado para exibir os elementos da pilha, o que é feito com o uso da estrutura de repetição for, que repete o processo de exibição do valor do elemento e da posição que ele ocupa até que a variável de controle i atinja o valor do total de elementos. A classe usaPilha possibilita que o usuário selecione a opção desejada para manipulação da pilha e utiliza todos os métodos que implementamos na classe Pilha. Java: classe que utiliza uma pilha 1.
import java . i o . * ;
2.
class usaPilha {
3.
()
publ ic static void escolhas
{
4.
System . o u t . print ( "Escolha a Opcao : " ) ;
5.
System . o u t . print ( " \n1 . Inserir" ) ;
6.
System . o u t . print
( " \n2. Excluir " ) ;
7.
System . o u t . print
(
"
\n3. Exibir a Pilha" ) ;
8.
System . ou t . print
(
"
\n4. Sair" ) ;
9.
System . ou t . print
( " \n. Opcao : \t " ) ;
10. 11.
} public static void main (String args ( ] ) (
12.
Pilha objPilha = new Pilha ( 10 } ;
13.
BufferedReader entrada;
14.
entrada = new BufferedReader (
15.
new InputStreamReader (System . i n ) ) ;
16.
Object valor;
17. 18.
try {
escolhas ( )
;
19.
char opcao = entrada . readLine ( ) . charAt ( O ) ;
20.
while
(opcao ! = ' 4 ' )
21.
switch ( opcao)
22.
case ' 1 '
23.
if
(
{
:
(objPilha . cheia ( )
== false)
24.
{ System . o u t . print
( "Digite algo:
25.
valor = entrada . readLine ( ) ;
26.
objPilha. empilhar (valor} ;
27.
}
28.
el s e
29.
{System . out . printl n ( "Fila Cheia ! " ) ;
30.
}
31.
break ;
32.
");
case ' 2 '
:
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS '
220
33.
if
34.
(objPilha . vazia ( )
==
{System . o u t . println (objPilha . desempilhar ( ) ) ;
35.
)
36.
else { System . out . println ( "Fila Vazia! " ) ;
37. 38.
}
39.
break;
40 .
case ' 3 '
:
41.
obj Pilha. exibePilha ( ) ;
42 .
break;
43 .
default :
System . o u t . println ( "Opcao Invalida ! " ) ;
44.
}
45 .
System . o u t . println ( ) ;
46.
escolhas ( ) ;
47 .
opcao
48.
}
49.
50.
=
entrada . readLine ( ) . charAt ( O ) ;
} catch
(Exception erro ) {
System . out .println ( "Erro de Entrada de Dados" ) ;
51.
}
52 . 53 .
false)
}
)
/
1 0. 6 ARVORES
Uma árvore é uma estrntura de dados bidimensional, não linear, que possui pro priedades especiais e admite muitas operações de conjuntos dinâmicos, tais como: consulta, inserção, remoção, entre outros. E diferente das listas e pilhas, uma vez que estas são estruturas de dados lineares. Uma árvore, de modo geral, possui as seguintes características: ,
'
•
nó raiz - nó do topo da árvore, do qual descendem os demais nós. E o primeiro nó da árvore;
•
nó interior - nó do interior da árvore (que possui descendentes);
•
nó terminal - nó que não possui descendentes;
•
trajetória - número de nós que devem ser perconidos até o nó determinado;
•
grau do nó - número de nós descendentes do nó, ou seja, o número de subárvores de um nó;
•
grau da árvore - número máximo de subárvores de um nó;
•
altura da árvore - número máximo de níveis dos seus nós;
•
altura do nó - número máximo de niveis dos seus nós.
Para exemplificar a explicação sobre as características de uma árvore, vamos fazer uma análise da árvore apresentada na Figura 10.20:
CAPITULO 1 0 - ESTRUTURAS D E DADOS DINAMICAS '
A
.
.. . . ...
.. . ....
.··
···
..
.
.
221
.... . .
b
.. e
d
..
..
.
.
f ··.. .
.
. .
.
J
! FIGURA
•
•
•
10.201 Ánrores
o nó a é denominado nó raiz, tem grau dois pois possui dois filhos, os nós Q e c, que também podem ser chamados de subárvores ou nós descendentes; o nó b tem grau três pois possui três filhos: os nós d, e e f; o nó b também é denominado pai dos nós Q, � e f;, os nós Q_e e são nós terminais, isto é, não possuem descendentes e por isso tem grau zero; A
•
o nó f tem grau dois e tem como filhos os nós i e t
•
o nó i é um nó terminal e possui grau zero;
•
o nó l tem grau um e é pai do nó k, que é terminal;
•
o nó º tem grau dois e é pai dos nós g e h, que são nós terminais;
•
•
•
a árvore possui grau três, pois este é o número máximo de nós descendentes de um únko pai; a árvore tem altura igual a 5, já o nó b tem altura igual a 4, o nó c tem altura igual a 2, o nó k tem altura igual a 1 e assim por diante; para defulirmos a trajetória a ser percorrida vamos supor que se deseje chegar ao nó j, então o caminho a ser percorrido seria ª' Q, f, j, conforme ilustrado na Figura 1 0.21 .
As árvores podem ser do tipo listas generalizadas ou binárias. As árvores do tipo listas generalizadas possuem nós com grau maior ou igual a zero, enquanto uma árvore do tipo binária sempre possui nós com grau menor ou igual a 2. Veja os exemplos de árvores apresentados na Figura 10.22. Neste livro trataremos apenas das árvores binárias. /
,
1 0.6. 1 ARVO R E S 8 1 N A RIA S
Conforme já dissemos anteriormente, uma árvore binária sempre possui nós com grau menor ou igual a dois, isto é, nenhum nó possui mais do que dois descendentes
-
LOGICA D E PROGRAMAÇAO E ESTRUTURAS DE DADOS '
222
.. ...
... . . . . ..
...
.
.
. ..
.. ....
.
.
. .. ... . .
. .
..
..
J
k
1 o. 2 1 I Trajetória
I FIGURA
.
.
Arvore como lista generalizada
Arvore binária
d
k ! FIGURA
'
10.221 Arvores
57
45
25
I FIGURA
10.231 Árvore binária
CAPÍTULO 1 0 - ESTRUTURAS D E DADOS DINÂMICAS
223
diretos (dois filhos). Nesse tipo de árvore também existe uma particularidade quanto à posição dos nós: os nós da direita sempre possuem valor superior ao do nó pai, e os nós da esquerda sempre possuem valor inferior ao do nó pai. O algoritmo a seguir representa as variáveis que serão utilizadas para a manipu lação da árvore - note que existe grande similaridade com os nós criados para mani pulação das listas. O algoritmo tem a definição de um registro que possui as variáveis valor, esq e dir, a variável apontador, que será utilizada para fazer a referência a nós localizados à diJeita e à esquerda (da raiz ou do nó pai), e a variável raiz, que guardará o valor do nó raiz da árvore. EXEMPLO 10.15: Pseudocódigo que representa 1.
uma sao deri\ados da supereiasse Throwable, conforme pode ser llh..,ervado na Figura J. O
DESCR I ÇÃO D E A L G U M A S C L A S S E S Excep t i on -
"ão cxt:eçiks genérica." que devem ser tratadas.
Error - �ão eiTo..,
gra\c.., qut.> normalmente não podem ser tratados.
RunTimeException -
"ão as exceçõe' geradas por erros de programação.
é uma exceção as\ociada à tentativa de acesso a propriedades ou métodos de n:ferências com valor null. Nu l l PointerException -
ArithrneticException
ção incorreta de operadores
- l! uma exceção associada à tentativa de utiliza
aritméticos
como. por exe mplo. a divisão por zero.
IndexOut:OfBoundsException -
é uma exceção
a..,o;;ociada
a índices de
Yetoró ou ...tring�. ArrayStoreException - é uma exceção
um
gerada pela tentativa de atribuir a el ememo de um array um objl.!to inco mpatíve l com o tipo declarado do array. A captura das exceções ucvc ser fei ta da segu i n te forma : try
{ 1
código que PODE gerar
catch ( Exception e )
��a
exceção
{ / / captura da exceçao
/ 1 código executado no tratamento da exceção
Senuo
que o código que pouc gerar uma exceção deve ser descrito no bloco try. Es�as exceções. por sua \·ez.. \ão capturadas no bloco c atch ( ) . que deve especificar os argumentos (exceções a serem tratadas). Passagem da exceção pelo método: voia metodo l ( )
thr:ows
IOException
{
1 1 código que pode gerar uma exceção IOException
Lançamento de exceção: VOld metodo2 ( )
throws
IOException
{
1 1 testa condição de exceção i f ( cxcep)
}
then throw ( new IOException ( ) ) ;
LÓGICA D E PROGRAMAC, ÂO E ESTRUTURA S DE DAD os
244
Throwable
t
J -1
Error
Except1on _
L llegalAccessException
LmkageError ThreadDeatn
lnstan t ia t10n Exce ptio n
ed Except1 on p lnrerru pted Excepti o n e
Clon No tSu port
r
NoSuc:hMethodExceptlon
ClassNot Fou n d E xceptlo n
-l
VirtuaiMach1neError
�
--l
AWTError
l
AWTException
u
e x t IOExceptio n --- �
R n ti m E cep ion
Runti meException
IEmptySrockExceptiOn -----! NoSuctlElementExceptJon
IAnthmeticExcept on ;
ArrayStoreException
1ClassCastException
tEx _ _ a IA _ _ r gum en _ _ _ _ ce_ p_ tio n ----j 11 11 eg l l legaiMonltOrStateExceptlon
lndexOutOfBoundsExcept1on r
NuliPointe Exceptton
x
lnterruptediOException
UTFDataFormatException
,_ MalformedURLExcept1on
o
t o
lncompatibleClassChangeError
�lassDefFoundError
I Unsat1sfieldlinkError I VerifyError I
UnknownHostExceptton
e
_ _ .....l _
____J
I:
I I I I
StringlndexOutOfBoundsException
tNurnber�rrnatExcep _ _ t_ ion = �J �- ---�
I I I
I I
I I
Abstract MethodError llegaiAccessError
Insta n lta tlonError NoSuchFieldError NoSuchMethodError
_..
_ _ _ _ _ _ _
I
I FIGURA 3 1 Hiert:
data)
é anterior e um
-
retoma
O �e a data é igual
a
positivo se é posterior
.
Exemplos . Date u��a.
=
ne� Date ( ) ;
Date data2
=
new Date ( ) ;
System . ou t . println ( " Resposta:
3.
-
�
datal . a fter ( da�a2 ) ) ;
CLAS S E S D E E NTRA DA E S A ÍDA j a7a . i o . Buff eredReader
ti lt ro que age sobre um Read r. adicio e nando um buffcr c oLimiLando o acel.so aos dauo'
ANC:XO: CONCEITOS S O B R E A I .. I N G U A G E M JAVA
247
C O N S T R U TO R E S
éJ
new Buff eredReader ( Peader rd) constrói u m BufferedReader p:.tri ir de um Reader rd. com hullcr de tamanho tlefault.
P R I N C I PA I S M ÉTODOS publ i c
int
read ( )
int
read
IOException - lê u m caractere da
throws
entrada-pad rão. publ i c
[]
( char
c,
int
inicio ,
int
quant)
IOExcept i o n - lê uma scqüêm:ta quant de caracteres e a coloca no
throws
arruy c a partir da po:-. i�·ão dada pnr i n i c i o . Retoma o número de caracteres lidos
(-1
->C não houver caractere" para ler) publ i c S t ring readLine ( )
throws
IOExcept i on - lê uma linha
de caral'lcre'>. void
puo l i c
close ( )
throws
IOExcept ion - fecha o Reader .
Exemplo: BufferedReaàer arq
=
String rry
arq;
new BufferedReader
( new FileReader
( " arquivo " ) ) ;
:inha ;
{ linha
} catcb
- arq. readLine ( ) ;
{
( IOExcepcion e )
}
j ava . i o . Buf feredWri ter
nando um buffer e
-
fiJn·o que age sobre um Writer. adicio
otirmzando o acc..,so aoc., dado">.
CO N S T R U TO R E S new BufferedWr i ter
( W r i t e r wr )
constrói u m BufferedWriter
a partir de um Wri t e r wr. com buffer de tamanho default.
P R I N C I PA I S M ÉTODOS public
void writ e ( in t
c}
throws
IOExcep t i o n - escreve um
caracter na saída. pub l i c throws
void w r i t e r
( c har
[]
c,
int
ini c i o ,
int quant )
IOExc e p t i on - escreve quant caracteres no array c a partir da posição
dada por i n i c i o . publ i c
void
newLine ( }
publ i c
void
flush ( )
throws
IOException - inicia u ma
nova
linha. throws
IOException - descarrega
j
a
saídas
forç�ndo a csaída específi para arqui' 0,. cujo acc��o não prcci �a ,er -.eqüencial. Pcnmtc c..,pcc l flcar :-e o modo
de acec;..,o ,era ...omcntc para kJtura ou para e:-.crita c leitura.
CONSTRUTO R E S public RandomAcces sFi l e ( S tring arq,
String modo ) throws
IOException - cria um objeto para acesso a arquivo e o as..,oc w ao arquivo especi ficado em arq: modo e"pcdlictl o modo de acesso que pode 'ier: r (somente para leitura ) ou n.,r l lciLUn.l c c-.crita). public RandomA(.;cessFile ( F i l e arq ,
S t r i ng modo)
throws
IOException - cria um obj eto para acesso a arquivo e o as..,ocia ao arquivo especi ficado por leitura) ou
arq: modo rw
espec1tica o modo de ace 'iO que pode \er:
(leitura c escnta).
r
(Cartados. pub lic void seek ( long x) t hrows rr�Exc ept�o pustctona o n . . cursor de lcttu rall.!sCJJta na postçao x do arquivo (em bytc\) l ic long ge tF ile Po in p te r ( ) throws IO Ex cep tio n retorna a pos1çao conl.!nlc do cursor, em bytes. ·
·
.
��
publ ic long skipBytes ( lo ng x ) carla x byt�.:s da entrada.
·
_
_
_
thl·ows
IOExce pt ion - de ·
249
l ong length ( ) thr ows IOE xcep tion - reto b� 1es. m ma o tamanho e O . Jlli\ [ll lll , pub l i c void setl ength ( l ong � . x ) throws IO Exception l a rqu i\O em byteo., l&.l.lllanI10