Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As...

36
1 João Miguel da Costa Sousa 177 Tabelas unidimensionais Tipos de dados simples: real, inteiro, complexo, etc. Necessidade de processamento de vários valores simultaneamente pode tornar-se muito moroso. Exemplos: Lista de resultados Conjunto de medidas matrizes, etc. Tipos de dados estruturados Tabelas Fichas João Miguel da Costa Sousa 178 Exemplo: Detecção de avarias Este programa recebe os tempos de avaria de vários componentes e pretende-se saber como medida de fiabilidade o tempo médio de falha de cada um dos componentes. O programa deverá seguir os seguintes passos: Calcular o tempo médio de avaria. Imprimir a lista de avarias maior do que a média. Ordenar os tempos de avaria de forma ascendente. A lista de avarias é assim processada várias vezes. São propostas três soluções: 1. Utilizar uma variável para cada tempo de avaria 2. Reler os dados sem atribuir um a cada variável 3. Utilizar uma tabela unidimensional

Transcript of Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As...

Page 1: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

1

João Miguel da Costa Sousa 177

Tabelas unidimensionais

� Tipos de dados simples:� real,

� inteiro,

� complexo, etc.

� Necessidade de processamento de vários valores simultaneamente pode tornar-se muito moroso. Exemplos:� Lista de resultados

� Conjunto de medidas

� matrizes, etc.

� Tipos de dados estruturados

� Tabelas

� Fichas

João Miguel da Costa Sousa 178

Exemplo: Detecção de avarias

� Este programa recebe os tempos de avaria de vários componentes e pretende-se saber como medida de fiabilidade o tempo médio de falha de cada um dos componentes. O programa deverá seguir os seguintes passos:� Calcular o tempo médio de avaria.� Imprimir a lista de avarias maior do que a média.� Ordenar os tempos de avaria de forma ascendente.

� A lista de avarias é assim processada várias vezes. São propostas três soluções:1. Utilizar uma variável para cada tempo de avaria2. Reler os dados sem atribuir um a cada variável3. Utilizar uma tabela unidimensional

Page 2: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

2

João Miguel da Costa Sousa 179

Programa: Tempos_de_avaria1 (1)

� Esboço do programa:PROGRAM Tempos_de_avaria1

!-----------------------------------------------------------

! Descricao do programa e das variaveis utilizadas.

!-----------------------------------------------------------

IMPLICIT NONE

INTEGER :: EstadoAbertura, EstadoEntrada

REAL :: TempoAvaria_1, TempoAvaria_2, TempoAvaria_3, &

TempoAvaria_4, TempoAvaria_5, TempoAvaria_6, &

! etc.

TempoAvaria_48, TempoAvaria_49, TempoAvaria_50, &

Tempo_Medio_Avaria

! Le os tempos de avaria

OPEN (UNIT = 10, FILE = “TEMP_IN.DAT”, STATUS = “OLD”, IOSTAT = EstadoAbertura)

IF (EstadoAbertura > 0)

WRITE (*, *) “Ficheiro nao disponivel!”

ELSE

READ (10, *, IOSTAT = EstadoEntrada) &

TempoAvaria_1, TempoAvaria_2, TempoAvaria_3, TempoAvaria_4, TempoAvaria_5, &

! etc.

TempoAvaria_48, TempoAvaria_49, TempoAvaria_50, &

IF (EstadoEntrada > 0)

WRITE(*, *) “Erro na entrada de dados”

ELSE IF (EstadoEntrada < 0)

WRITE(*, *) “Dados insufucientes”

ELSE

João Miguel da Costa Sousa 180

Programa: Tempos_de_avaria1 (2)

Tempo_Medio_Avaria = &

(TempoAvaria_1 + TempoAvaria_2 + TempoAvaria_3 + &

TempoAvaria_4 + TempoAvaria_5, TempoAvaria_6, &

! etc.

TempoAvaria_46 + TempoAvaria_47 + TempoAvaria_48 + &

TempoAvaria_49 + TempoAvaria_50) / 50.0

WRITE (*, *) “Tempo medio de avaria =”, &

Tempo_Medio_Avaria

! Mostra tempos acima da média

IF (TempoAvaria_1 > Tempo_Medio_Avaria) &

WRITE (*, *) TempoAvaria_1

IF (TempoAvaria_2 > Tempo_Medio_Avaria) &

WRITE (*, *) TempoAvaria_2

!

! etc., etc., etc.

!

IF (TempoAvaria_50 > Tempo_Medio_Avaria) &

WRITE (*, *) TempoAvaria_50

! Apos 200 linhas de codigo, ordenar os valores?!!

! Deve existir uma forma melhor de programar!!

END PROGRAM Tempos_de_avaria1

� Outra solução:� Reler os dados várias vezes para cada um dos cálculos necessários.

Page 3: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

3

João Miguel da Costa Sousa 181

Tabelas

� As soluções propostas são ineficientes; é necessária uma estrutura de dados para:� armazenar� organizar os dados de forma simples.

� Estrutura de dados deve poder ser acedida de forma não sequencial, ou ter um acesso directo.

� Estrutura pretendida: tabela (array).� Exemplo:

REAL, DIMENSION(50) :: TempoAvaria

� O compilador cria uma tabela com o nome TempoAvaria, consistindo em 50 espaços em memória do tipo REAL.

� Exemplo: TempoAvaria(34)

� o índice correspondendo ao elemento é 34.

João Miguel da Costa Sousa 182

Tabelas (cont.)

� Localização da tabela em memória:Memória

TempoAvaria(1) ←→

TempoAvaria(2) ←→

TempoAvaria(3) ←→

… …

TempoAvaria(50) ←→

� Índice deve ser uma variável ou expressão do tipo inteiro.� Leitura de tabelas:

READ (10, *) TempoAvaria

� é equivalente a:READ (10, *) TempoAvaria(1), (...), TempoAvaria(50)

Page 4: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

4

João Miguel da Costa Sousa 183

Programa: Tempos_de_avaria2 (1)

PROGRAM Tempos_de_avaria2

!------------------------------------------------------------

! Programa que le uma lista de tempos de avaria, calcula o

! tempo medio de avaria, mostra uma lista de tempos de avaria

! maiores que a media. Identificadores:

! EstadoAbertura : estado da variavel para OPEN

! EstadoEntrada : estado da variavel para READ

! TempoAvaria : tabela unidimensional de tempos avaria

! NumeroVezes : dimensao da tabela (constante)

! I : indice

! Soma : somados tempos de avaria

! Tempo_Medio : media dos tempos de avaria

!

! Entradas: Lista com NumeroVezes de tempos de avaria

! Saidas: Informacao sobre o estado do ficheiro de dados,

! Tempo_Medio, e uma lista com tempos de avaria

! maiores que Tempo_Medio

!------------------------------------------------------------

IMPLICIT NONE

INTEGER, PARAMETER :: NumeroVezes = 50REAL, DIMENSION(NumeroVezes) :: TempoAvariaINTEGER :: EstadoAbertura, EstadoEntrada, I

REAL :: Soma, TempoMedio

WRITE (*, *) “Programa le”, NumeroVezes, “tempos de avarias &

&no ficheiro entrada.dat.”

OPEN (UNIT = 10, FILE = “entrada.dat”, STATUS = “OLD”, &

IOSTAT = EstadoAbertura)

IF (EstadoAbertura > 0)

WRITE (*, *) “*** Ficheiro nao disponivel! ***”

João Miguel da Costa Sousa 184

Programa: Tempos_de_avaria2 (2)

ELSE

! Le os tempos de avaria e armazena-os em TempoAvariaREAD (10, *, IOSTAT = EstadoEntrada) TempoAvariaIF (EstadoEntrada > 0)

WRITE(*, *) “*** Erro na entrada de dados ***”

ELSE IF (EstadoEntrada < 0)

WRITE(*, *) “*** Dados insufucientes ***”

ELSE

! Calcula o tempo medio de avaria

Soma = 0.0

DO I = 1, NumeroVezesSoma = Soma + TempoAvaria(I)

END DOTempoMedio = Soma / REAL(NumeroVezes)

WRITE (*, ‘(1X, “Tempo medio de falha =”, F6.1)’,&

TempoMedio

! Mostra lista de tempos maiores que a media

WRITE(*, *)

WRITE(*, *) “Lista de tempos maiores que a media:”

DO I = 1, NumeroVezesIF (TempoAvaria(I) > TempoMedio) THEN

WRITE (*, ‘(1X, F9.1)’, TempoAvaria(I)END IF

END DOEND IF

END IF

END PROGRAM Tempos_de_avaria2

Page 5: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

5

João Miguel da Costa Sousa 185

Ficheiro de dados

�Listagem do ficheiro entrada.dat:

99.5, 133.8, 84.2, 217.5, 188.8, 103.1, 93.9, 165.0, 68.3

111.4, 88.8, 88.2, 90.1, 70.2, 150.5, 122.9, 138.8, 99.9

111.6, 155.7, 133.4, 122.2, 93.4, 101.5, 109.9, 103.3, 177.7

188.1, 99.8, 144.4, 87.5, 79.3, 190.2, 190.3, 170.1, 160.9

121.1, 95.6, 140.5, 177.2, 150.1, 140.3, 139.2, 113.8, 155.9

144.4, 88.3, 83.5, 101.1, 112.8

João Miguel da Costa Sousa 186

Exemplo de execução

> Programa le 50 tempos de avarias no ficheiro entrada.dat.

> Tempo medio de falha = 126.0

>

> Lista de tempos maiores que a media:

> 133.8

> 217.5

> 188.8

> 165.0

> 150.5

> 138.8

> 155.7

> 133.4

> 177.7

> 188.1

> 144.4

> 190.2

> 190.3

> 170.1

> 160.9

> 140.5

> 177.2

> 150.1

> 140.3

> 139.2

> 155.9

> 144.4

Page 6: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

6

João Miguel da Costa Sousa 187

Leitura e escrita de tabelas

�Leitura e escrita de tabelas

� Exemplo leitura:READ (10, ‘(5F6.1)’) TempoAvaria

12345678901234567890123456789012345678901234567890

99.5 133.8 84.2 217.5 188.8

103.1 93.9 165.0 68.3 111.4

etc.

� Exemplo escrita:WRITE (20, ‘(1X 5F10.1)’) TempoAvaria

João Miguel da Costa Sousa 188

Ciclos DO implícitos

� Definição:

(lista, var_controlo = inicial, limite, passo)

� Onde lista corresponde à lista de variáveis, e var_controlo, inicial, limite e passo são as mesmas variáveis de um ciclo DO.

� Exemplo leitura:READ (10,*) (TempoAvaria(I), I=1, NumeroVezes)

� é equivalente a:READ (10,*) TempoAvaria(1), TempoAvaria(2),&

..., TempoAvaria(NumeroVezes)

� Exemplo escrita:WRITE (*,*) (TempoAvaria(I), I=1, NumeroVezes)

� é equivalente a:WRITE (*,*) TempoAvaria(1), TempoAvaria(2),&

...,TempoAvaria(NumeroVezes)

Page 7: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

7

João Miguel da Costa Sousa 189

Definição de tabelas

Definição de tabelas compiladas_____________________________________________________________________

Forma:

tipo, DIMENSION(l:u) :: lista_nome_tabelas

outipo :: lista_especificadores_tabelas

� Onde:� a lista_nome_tabelas é uma lista de nomes de tabelas;� a lista_especificadores_tabelas é uma lista de especificadores

da forma:nome_tabela(l:u)

� Cada um dos identificadores da lista é uma tabela, cuja memória é atribuída (alocada) aquando da compilação do programa.

� Os índices vão de l a u são quaisquer inteiros. Se l é igual a 1, este valor pode ser omitido.

João Miguel da Costa Sousa 190

Exemplos de tabelas

� Exemplo anterior (TempoAvaria):REAL, DIMENSION(50) :: TempoAvaria

REAL, DIMENSION(1:50) :: TempoAvaria

REAL :: TempoAvaria(1:50)

REAL :: TempoAvaria(50)

� Exemplo 2:

INTEGER, PARAMETER :: LimInf_1 = -1, LimSup_1 = 3, &

LimInf_2 = 0, LimSup_2 = 5

INTEGER, DIMENSION(LimInf_1:LimSup_1) :: Gama

REAL, DIMENSION(LimInf_2:LimSup_2) :: Delta

� Gama tem 5 elementos e Delta 6 elementos.

Page 8: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

8

João Miguel da Costa Sousa 191

Tabelas alocáveis

�Na versão anterior, é associado um bloco de memória para toda a tabela, o qual não pode ser alterado.

�Problemas:� Se tamanho indicado é maior do que o necessário, existe

memória desperdiçada

� Se tamanho indicado é menor do que o necessário, há erro de overflow da tabela.

�Fortran não permite alocar memória após a declaração da tabela

�Solução: alocar memória durante execução

João Miguel da Costa Sousa 192

Tabelas alocáveis

Definição de tabelas alocáveis____________________________________________________________________

Forma:

tipo, DIMENSION(:), ALLOCATABLE :: lista

outipo, DIMENSION(:) :: lista

ALLOCATABLE :: lista

� Onde a variável lista é uma lista de tabelas.

� Declara que o tamanho de cada uma das tabelas em lista será especificado durante a execução.

� Exemplo:

REAL, DIMENSION(:), ALLOCATABLE :: A, B

Page 9: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

9

João Miguel da Costa Sousa 193

Instrução ALLOCATE

Instrução ALLOCATE____________________________________________________________________

Forma:

ALLOCATE(lista)

ouALLOCATE(lista, STAT = estado_variavel)

� Onde a variável lista é uma lista de especificações de tabelas da forma:nome_tabela(l:u)

� Atribui espaço em memória para cada uma das tabelas da lista.

� Na segunda forma, à variável estado_variavel é atribuído o valor zero se a alocação for bem sucedida. Se não existir mais memória ou a tabela já tiver sido previamente alocada, é atribuído um valor de erro.

� Existe uma pilha de memória disponível quando o programa começa a ser executado. Cada ALLOCATE vai utilizar espaço dessa memória (alocá-lo).

João Miguel da Costa Sousa 194

Instrução DEALLOCATE

� Como a memória é limitada, dever-se-á libertar espaço em memória sempre que este não é necessário.

Instrução DEALLOCATE____________________________________________________________________

Forma:

DEALLOCATE(lista)

ouDEALLOCATE(lista, STAT = estado_variavel)

� Onde a variável lista é uma lista de tabelas previamente alocadas.

� Liberta a memória previamente utilizada. À variável estado_variavel é atribuído o valor zero se a desalocação for bem sucedida. A memória libertada passa a estar disponível.

Page 10: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

10

João Miguel da Costa Sousa 195

Programa: Tempos_de_avaria3 (1)

PROGRAM Tempos_de_avaria3

!----------------------------------------------------------------------------------

! Programa que le uma lista de tempos de avaria, calcula o tempo medio de avaria e

! mostra uma lista de tempos de avaria maiores que a media. E utilizada uma tabela

! alocada para guardar os tempos de avaria. Identificadores:

! NomeFicheiro : nome do ficheiro de dados

! EstadoAbertura : estado da variavel para OPEN

! EstadoEntrada : estado da variavel para READ

! EstadoAlocacao : estado da variavel para ALLOCATE

! TempoAvaria : tabela unidimensional de tempos avaria

! NumeroVezes : dimensao da tabela (variavel)! I : indice

! Soma : somados tempos de avaria

! Tempo_Medio : media dos tempos de avaria

!

! Entrada(teclado) : NomeFicheiro

! Entrada(ficheiro): NumeroVezes e lista com NumeroVezes de tempos de avaria

! Saidas: Tempo_Medio e uma lista com tempos de avaria maiores que Tempo_Medio

! Nota: Primeiro valor do ficheiro deve conter NumeroVezes

!-----------------------------------------------------------------------------------

IMPLICIT NONE

CHARACTER(20) :: NomeFicheiro

REAL, DIMENSION(:), ALLOCATABLE :: TempoAvaria

INTEGER :: EstadoAbertura, EstadoEntrada, EstadoAlocacao, NumeroVezes, I

REAL :: Soma, TempoMedio

! Le o nome do ficheiro de dados e abre-o para entrada

WRITE (*, ‘(1X, A)’, ADVANCE = “NO”) “Escreva o nome do &

&ficheiro de dados: ”

READ (*, *) NomeFicheiro

João Miguel da Costa Sousa 196

Programa: Tempos_de_avaria3 (2)

OPEN (UNIT = 10, FILE = NomeFicheiro, STATUS = “OLD”, IOSTAT = EstadoAbertura)

IF (EstadoAbertura > 0)

WRITE (*, *) “*** Ficheiro nao disponivel! ***”

ELSE

! Le o numero dos tempos de avaria e aloca uma tabela! com o numero de elementos a guardar os tempos de avariaREAD (10, *, IOSTAT = EstadoEntrada) NumeroVezes IF (EstadoEntrada > 0) WRITE(*, *) “*** Erro na entrada de dados ***”

ELSE IF (EstadoEntrada < 0) WRITE(*, *) “*** Dados insufucientes ***”

ELSEALLOCATE(TempoAvaria(NumeroVezes), STAT = EstadoAlocacao)

END IFIF (EstadoAlocacao /= 0)WRITE(*, *) “*** Memoria Insuficiente ***”

ELSE

! Le os tempos de avaria e armazena-os em TempoAvaria

READ (10, *, IOSTAT = EstadoEntrada) TempoAvaria

IF (EstadoEntrada > 0)

WRITE(*, *) “*** Erro na entrada de dados ***”

ELSE IF (EstadoEntrada < 0)

WRITE(*, *) “*** Dados insufucientes ***”

ELSE

! Calcula o tempo medio de avaria

Soma = 0.0

DO I = 1, NumeroVezes

Soma = Soma + TempoAvaria(I)

END DO

Page 11: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

11

João Miguel da Costa Sousa 197

Programa: Tempos_de_avaria3 (3)

TempoMedio = Soma / REAL(NumeroVezes)

WRITE (*, ‘(/ 1X, “Para ”, I4, “tempos de avaria, ” &

/ 1X, “o tempo medio de avaria =”, F6.1)’) Numero Vezes, TempoMedio

! Mostra lista de tempos maiores que a media

WRITE(*, *)

WRITE(*, *) “Lista de tempos maiores que a media:”

DO I = 1, NumeroVezes

IF (TempoAvaria(I) > TempoMedio) THEN

WRITE (*, ‘(1X, F9.1)’) TempoAvaria(I)

END IF

END DO

! Liberta espaco em memoria de TempoAvaria

DEALLOCATE(TempoAvaria)

END IF

END IF

END IF

END PROGRAM Tempos_de_avaria3

� Hipótese de verificação de alocação para libertar a memória correspondente a uma dada variável:IF (ALLOCATED(TempoAvaria)) THEN

DEALLOCATE(TempoAvaria)

END IF

João Miguel da Costa Sousa 198

Processamento de tabelas

� As tabelas constantes são uma lista de valores entre (/ e /).

(/ valor_1, valor_2, ..., valor_k /)

� Exemplo 1:

(/ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 /)

� Podem ser dadas por um DO-implícito:

(/ valor-lista, controlo-DO-implícito /)

� Exemplo 2:

(/ (2*I, I = 1, 10) /)

Page 12: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

12

João Miguel da Costa Sousa 199

Expressões e atribuições

� Operadores e funções são aplicáveis a tabelas com o mesmo número de elementos.

� Exemplos:INTEGER, DIMENSION(4) :: A, B

INTEGER, DIMENSION(0:3) :: C

INTEGER, DIMENSION(6:9) :: D

LOGICAL, DIMENSION(4) :: P

A = (/ 1, 2, 3, 4 /)

B = (/ 5, 6, 7, 8 /)

A = A + B

C = (/ -1, -3, -5, 7 /)

D = 2 * ABS(C) + 1

P = (C > 0) .AND. (MOD(B, 3) == 0)

� Atribuiçõesvariavel_tipo_tabela = expressao

� Valores da expressão atribuída podem ser:1. Uma tabela do mesmo tamanho da variável.2. Um valor simples. Neste caso o valor é atribuído a todos os elementos da

tabela.

João Miguel da Costa Sousa 200

Sub-tabelas

� Definição:nome_tabela(inferior:superior:passo)

ounome_tabela(vector_indices)

� Exemplo 1:INTEGER, DIMENSION(8) :: A

INTEGER, DIMENSION(4) :: B

INTEGER :: J

� SeA = (/ 11, 22, 33, 44, 55, 66, 77, 88 /)

� então:B = A(2:8:2)

� é a parte de A com os elementos 22, 44, 66 e 88.

� Exemplo 2:I = (/ 6, 5, 3, 8 /)

B = A(I)

� atribui a B os elementos 66, 55, 33, 88.B = A((/ 5, 3, 4, 3/))

� atribui a B os elementos 55, 33, 44, 33.

Page 13: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

13

João Miguel da Costa Sousa 201

A construção WHERE

Construção WHERE____________________________________________________________________

Forma:

WHERE (exp_log_tab) var_tab_1 = exp_tab_1

ouWHERE (expressao_logica_tabela)

var_tabela_1 = expressao_tabela_1

...

var_tabela_m = expressao_tabela_m

ELSEWHERE

var_tabela_m+1 = expressao_tabela_m+1

...

var_tabela_n = expressao_tabela_n

END WHERE

� A variável expressao_logica_tabela é uma tabela de expressões de valores lógicos;

� Cada var_tabela_i tem a mesma dimensão de expressao_logica_tabela;� Na segunda forma ELSEWHERE é opcional.

João Miguel da Costa Sousa 202

Tabelas como argumentos

� Exemplo com construção WHERE:

INTEGER, DIMENSION(5) :: A = (/ 0, 2, 5, 0, 10/)

REAL, DIMENSION(5) :: B

WHERE (A > 0)

B = 1.0 / REAL(A)

ELSEWHERE

B = -1.0

END WHERE

� Atribui a B a sequência -1.0, 0.5, 0.2, -1.0, 0.1.

� Tabelas como argumentos� Subprogramas com processamento de tabelas intrínseco. Exemplos:

ALLOCATED(A)

MAXVAL(A)

MAXLOC(A)

PRODUCT(A)

SIZE(A)

SUM(A)

Page 14: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

14

João Miguel da Costa Sousa 203

Subprogramas com tabelas

�Subprogramas definidos pelo programador� O argumento tipo tabela deve ser definido na unidade que

chama o subprograma.

� O argumento formal do tipo tabela deve ser declarado dentro do subprograma.

João Miguel da Costa Sousa 204

Programa: Media_de_uma_lista_1

PROGRAM Media_de_uma_Lista_1

!------------------------------------------------------------

! Programa que le uma lista de numeros Item(1), Item(2), …,

! Item(NumItems) e calcula a sua media usando a funcao Media.

! Os identificadores sao:

! Item : tabela uni-dimensional de numeros

! NumItems : numero de items (constante)

! Media : funcao que calcula a media de um conjunto de

! numeros

!

! Entradas : NumItems e a lista de numeros reais

! Saida : A media dos numeros

!------------------------------------------------------------

IMPLICIT NONE

INTEGER, PARAMETER :: NumItems = 10REAL, DIMENSION(NumItems) :: Item

WRITE (*, *) “Insira”, NumItems, “numeros reais:”

READ (*, *) Item

WRITE (*, ‘(1X, “Media de ”, I3, “numeros e:”, F6.2)’) &NumItems, Media(Item)

Page 15: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

15

João Miguel da Costa Sousa 205

Media_de_uma_lista_1 (concl.)

CONTAINS

!-Media---------------------------------------------------! Funcao que calcula a media de elementos de uma tabela X ! Identificadores locais:! NumElementos: numero de elementos em X (constante)!! Recebe : Tabela X! Retorna : A media dos valores guardados em X!---------------------------------------------------------FUNCTION Media(X)

INTEGER, PARAMETER :: NumElementos = 10REAL, DIMENSION(NumElementos), INTENT(IN) :: XREAL :: Media

Media = SUM(X) / REAL(NumElementos)END FUNCTION Media

END PROGRAM Media_de_uma_Lista_1

� Exemplo de execução:> Insira 10 numero reais:

> 55, 88.5, 90, 71.5, 100, 66.5, 70.3, 81.2, 93.7, 41

> Media de 10 numeros e 75.77

João Miguel da Costa Sousa 206

Programa: Media_de_uma_lista_2

PROGRAM Media_de_uma_Lista_2

!------------------------------------------------------------

! Programa que le uma lista de numeros Item(1), Item(2), …,

! Item(NumItems) e calcula a sua media usando a funcao Media.

! Os identificadores sao:

! Item : tabela uni-dimensional de numeros

! NumItems : numero de items (constante)

! Media : funcao que calcula a media de um conjunto de

! numeros

!

! Entradas : NumItems e a lista de numeros reais

! Saida : A media dos numeros

!------------------------------------------------------------

IMPLICIT NONE

INTEGER, PARAMETER :: NumItems = 10

REAL, DIMENSION(NumItems) :: Item

WRITE (*, *) “Insira”, NumItems, “numeros reais:”

READ (*, *) Item

WRITE (*, ‘(1X, “Media de ”, I3, “numeros e:”, F6.2)’) &

NumItems, Media(Item, NumItems)

Page 16: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

16

João Miguel da Costa Sousa 207

Media_de_uma_lista_2 (concl.)

CONTAINS

!-Media---------------------------------------------------

! Funcao que calcula a media de NumElementos de uma tabela

! X. O tamanho da tabela X (NumElementos) é passado como

! argumento.

!

! Recebe : Tabela X e NumElementos

! Retorna : A media dos valores guardados em X

!---------------------------------------------------------

FUNCTION Media(X, NumElementos)

INTEGER, INTENT(IN) :: NumElementos

REAL, DIMENSION(NumElementos), INTENT(IN) :: X

REAL :: Media

Media = SUM(X) / REAL(NumElementos)

END FUNCTION Media

END PROGRAM Media_de_uma_Lista_2

João Miguel da Costa Sousa 208

Tabela Item alocada

�A tabela Item poderia ser alocada:! ...

INTEGER :: NumItems, EstadoAlocacao

REAL, DIMENSION(:), ALLOCATABLE :: Item

REAL :: Media

WRITE (*, ‘(1X, A)’, ADVANCE = “NO”) &

“Quantos elementos existem no conjunto de dados? ”

READ (*, *) NumItems

ALLOCATE(Item(NumItems), STAT = EstadoAlocacao)

IF (EstadoAlocacao /= 0) THEN

WRITE (*, *) “*** Memoria insuficiente ***”

ELSE

WRITE (*, *) “Insira”, NumItems, “numeros reais:”

READ (*, *) Item

WRITE (*, ‘(1X, “Media de ”, I3, “numeros e:”, F6.2)’) &

NumItems, Media(Item, NumItems)

END IF

!...

Page 17: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

17

João Miguel da Costa Sousa 209

Tabelas de dimensão pré-definida

� A dimensão da tabela actual é a dimensão da tabela formal (no subprograma).

Declaração:

DIMENSION(:)

ouDIMENSION(limite_inferior:)

� Onde limite_inferior especifica o limite inferior dos índices da tabela formal.

� Exemplo: No programa Media_de_uma_lista_2, a função média seria dada por:

! (...)

FUNCTION Media(X)

REAL, DIMENSION(:), INTENT(IN) :: X

REAL :: Media

Media = SUM(X) / REAL(SIZE(X))

END FUNCTION Media

João Miguel da Costa Sousa 210

Tabelas automáticas

� Um subprograma com tabelas de dimensão pré-definida pode necessitar de variáveis locais do tipo tabela.

� Usam-se tabelas automáticas neste caso, onde o seu tamanho varia com a chamada.

� A função SIZE dimensiona estas tabelas.� Exemplo:

!-Troca----------------------------------------------------

! Esta subrotina troca duas tabelas de dimensão pre-

! assumida. Tabela local utilizada:

! Temp : Tabela automatica utilizada para trocar A e B

!

! Aceita: Tabelas A e B

! Retorna: A e B com elementos trocados

!----------------------------------------------------------

SUBROUTINE Troca(A, B)

REAL, DIMENSION(:), INTENT(INOUT) :: A, B

REAL, DIMENSION(SIZE(A)) :: Temp

Temp = A

A = B

B = Temp

END SUBROUTINE Troca

Page 18: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

18

João Miguel da Costa Sousa 211

Funções que retornam tabelas

� Exemplo: Inversão de valores duma tabela

PROGRAM Inversao_de_uma_Lista

!------------------------------------------------------------

! Programa que testa a funcao Inverte. Le uma lista de

! numeros Item(1), Item(2), …, Item(NumItems), chama a funcao

! Inverte, constroi uma lista na ordem inversa e mostra-a.

! Os identificadores sao:

! Item : tabela unidimensional de numeros

! NumItems : numero de items (constante)

! Inverte : funcao que inverte a tabela

!

! Entradas : NumItems e a lista de numeros inteiros

! Saida : A lista invertida

!------------------------------------------------------------

IMPLICIT NONE

INTEGER, PARAMETER :: NumItems = 10

REAL, DIMENSION(NumItems) :: Item

WRITE (*, ‘(1X, A, I3, A)’, ADVANCE = “NO”) &

“Insira”, NumItems, “numeros inteiros: ”

READ (*, *) Item

WRITE (*, *) “A lista por ordem inversa e dada por:”

WRITE (*, *) Inverte(Item)

João Miguel da Costa Sousa 212

Inversao_de_uma_lista (concl.)

CONTAINS

!-Inverte-------------------------------------------------! Funcao que inverte uma tabela X. Variaveis locais:! NumElementos : numero de elementos em X! I : indice!! Recebe : Tabela X de dimensão predefinida! Retorna : A tabela X invertida!---------------------------------------------------------FUNCTION Inverte(X)

INTEGER, DIMENSION(:), INTENT(IN) :: XINTEGER, DIMENSION(SIZE(x)) :: InverteINTEGER :: NumElementos, I

NumElementos = SIZE(X)DO I = 1, NumElementos

Inverte(I) = X(NumElementos - I + 1)END DO

END FUNCTION Inverte

END PROGRAM Inversao_de_uma_Lista

� Exemplo de execução:> Insira 10 numero inteiros: 1 2 3 4 5 6 7 8 9 10

> A lista por ordem inversa e dada por:

> 10 9 8 7 6 5 4 3 2 1

Page 19: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

19

João Miguel da Costa Sousa 213

Algoritmos de ordenação

� Arranjo dos elementos de uma tabela de forma ascendente ou descendente.� Selecção simples� Ordenação rápida

� Ordenação por selecção simples

� Verifica a lista várias vezes, e de cada vez selecciona um elemento da lista colocando-o na posição correcta.

� Exemplo: ordenar de forma ascendente67, 33, 21, 84, 49, 50, 75

1. Localizar o elemento mais pequeno:

67, 33, 21, 84, 49, 50, 752. Trocá-lo com o primeiro:

21, 33, 67, 84, 49, 50, 753. Localizar o 2º elemento mais pequeno e ordená-lo (já se encontra na posição correcta

neste caso):

21, 33, 67, 84, 49, 50, 75(...) Repetem-se os passos até se obter a lista ordenada:

21, 33, 49, 50, 67, 75, 84

João Miguel da Costa Sousa 214

Ordenação por selecção simples

Algoritmo

� Algoritmo para ordenar uma lista de items X(1), X(2), …, X(N) de forma ascendente. Para ordenar de forma descendente procura o maior item em vez do menor de cada vez que a tabela é percorrida.

� Entrada: Lista X(1), X(2), …, X(N).

� Saída: Lista X(1), X(2), …, X(N) modificada ; os elementos estão na lista de forma ascendente.

Para I variando de 1 a N - 1, faz o seguinte:

� Na Iésima passagem, procura o ItemMaisPequeno na sublista X(I), …, X(N), e a sua respectiva posição LocalizacaoMaisPequeno.

� Troca ItemMaisPequeno com o item no princípio da lista.

� Atribui X(LocalizacaoMaisPequeno) o valor de X(I).

� Atribui X(I) o valor de X(LocalizacaoMaisPequeno).

Page 20: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

20

João Miguel da Costa Sousa 215

Subrotina: Ordenacao_por_seleccao

!-Ordenacao_por_Seleccao-------------------------------------------------------------

! Esta subrotina ordena a tabela Item em ordem ascendente usando o algoritmo de

! ordenacao por seleccao simples. Para ordenar em ordem descendente dever-se-a trocar

! MINVAL por MAXVAL e MINLOC por MAXLOC. Variaveis locais:

! NumItems : numero de elementos na tabela Item

! ItemMaisPequeno : item mais pequeno da sublista actual

! MINLOC_tabela : tabela de um elemento dada por MINLOC

! LocalMaisPequeno: localizacao de ItemMaisPequeno

! I : índice

!

! Aceita: Tabela de Items

! Retorna: Tabela com items ordenados de forma ascendente

!--------------------------------------------------------------------------------------

SUBROUTINE Ordenacao_por_Seleccao(Item)

INTEGER, DIMENSION(:), INTENT(INOUT) :: Item

INTEGER :: NumItems, ItemMaisPequeno, LocalMaisPequeno, I

INTEGER, DIMENSION(1) :: MINLOC_tabela

NumItems = SIZE(Item)

DO I = 1, NumItems - 1

! Encontra o item mais pequeno na sublista Item(I),...,Item(NumItems)

ItemMaisPequeno = MINVAL(Item(I:NumItems))

MINLOC_tabela = MINLOC(Item(I:NumItems))

LocalMaisPequeno = (I - 1) + MINLOC_tabela(1)

! Troca ItemMaisPequeno com Item(I) no inicio sublista

Item(LocalMaisPequeno) = Item(I)

Item(I) = ItemMaisPequeno

END DO

END SUBROUTINE Ordenacao_por_Seleccao

João Miguel da Costa Sousa 216

Ordenação rápida

� Escolhe-se um pivot, e trocam-se todos os elementos inferiores para um lado e todos os superiores para outro.

� Lista é dividida em duas mais pequenas e o procedimento é repetido.� Esta estratégia de dividir-para-reinar é implementada recursivamente de

forma natural.� Método mais eficiente; é um dos mais rápidos.� Exemplo: ordenar de forma ascendente

50, 30, 20, 80, 90, 70, 95, 85, 10, 15, 75, 251. O elemento pivot é o 50. Elementos maiores que 50 passam para a sua direita e

inferiores para a esquerda10, 30, 20, 25,15, 50, 95, 85, 70, 90, 75, 80

2. A lista é dividida em duas sublistas a ser ordenadas:10, 30, 20, 25,15 e95, 85, 70, 90, 75, 80

3. Os passos 1 e 2 podem ser aplicado a cada uma das duas sublistas mais pequenas de forma recursiva. O caso âncora (caso mais simples) ocorre quando a lista é vazia ou tem apenas um elemento.

Page 21: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

21

João Miguel da Costa Sousa 217

Ordenação rápida (concl.)

� O caso indutivo ocorre quando uma lista contém mais do que um elemento, onde:1. A lista é separada em duas sublistas.2. A sublista esquerda é ordenada recursivamente.3. A sublista direita é ordenada recursivamente.

� Subrotina: Ordenacao_Rapida!--------------------------------------------------------------------------------

! Nota: Nas subrotinas seguintes Item e uma tabela de

! tamanho predefinido; o programa principal deve:

! 1. conter uma subrotina como um subprograma interno,

! 2. importar a subrotina de um módulo, ou

! 3. conter um bloco de interface para esta subrotina.

!---------------------------------------------------------------------------------

!-Ordenacao_Rapida----------------------------------------------------------------

! Subrotina que ordena tabela usando o metodo de ordenacao rapida. Chama-a com

! Primeiro = limite inferior dos indices da tabela e Ultimo = limite superior.

! Variaveis locais:

! Media: ponto de separacao da tabela

!

! Aceita: Tabela Item

! Retorna: Tabela Item ordenada de forma ascendente

!---------------------------------------------------------------------------------

João Miguel da Costa Sousa 218

Subrotina: Ordenacao_Rapida

RECURSIVE SUBROUTINE Ordenacao_Rapida(Item, Primeiro, Ultimo)

INTEGER, DIMENSION(:), INTENT(INOUT) :: Item

INTEGER, INTENT(IN) :: Primeiro, Ultimo

INTEGER :: Medio

IF (Primeiro < Ultimo) THEN !Se tamanho lista >= 2

CALL Divide(Item, Primeiro, Ultimo, Medio) !Divide-a

CALL Ordenacao_Rapida(Item,Primeiro,Medio-1) !Ordena esq

CALL Ordenacao_Rapida(Item,Medio+1,Ultimo) !Ordena dir

END IF

END SUBROUTINE Ordenacao_Rapida

!-Divide-----------------------------------------------------

! Subrotina que divide uma lista em duas sublistas, usando o

! primeiro elemento como pivot, e retorna a posicao do

! elemento onde a lista e dividida. Variaveis locais:

! Esquerdo: posicao do primeiro elemento

! Direito : posicao do ultimo elemento

! Pivot : elemento pivot

! Troca : usado para trocar dois elementos

!

! Aceita: Tabela Item e posicoes Baixo e Alto do primeiro e

! do ultimo elementos.

! Retorna: Tabela Item ordenada de forma ascendente

!------------------------------------------------------------

SUBROUTINE Divide(Item, Baixo, Alto, Medio)

INTEGER, DIMENSION(:), INTENT(INOUT) :: Item

INTEGER, INTENT(IN) :: Baixo, Alto

INTEGER, INTENT(OUT) :: Medio

INTEGER :: Esquerdo, Direito, Pivot, Troca

Page 22: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

22

João Miguel da Costa Sousa 219

Subrotina: Divide

Esquerdo = Baixo

Direito = Alto

Pivot = Item(Baixo)

! Repete enquanto Esquerdo e Direito nao se encontrarem

DO

IF (Esquerdo >= Direito) EXIT

! Procura da direita para a esquerda elemento < pivot

DO

IF (Esquerdo>=Direito .OR. Item(Direito)<Pivot) EXIT

Direito = Direito - 1

END DO

! Procura da esquerda para a direita elemento > pivot

DO

IF (Item(Esquerdo) > Pivot) EXIT

Esquerdo = Esquerdo + 1

END DO

! Se Esquerdo e Direito nao se encontraram, troca items

IF (Esquerdo < Direito) THEN

Troca = Item(Esquerdo)

Item(Esquerdo) = Item(Direito)

Item(Direito) = Troca

END IF

END DO

! Troca elemento na posicao de separacao com pivot

Item(Baixo) = Item(Direito)

Item(Direito) = Pivot

Medio = Direito

END SUBROUTINE Divide

João Miguel da Costa Sousa 220

Algoritmos de procura

� Consideram-se dois tipos:� Procura linear� Procura binária

� Procura linear� Começa no primeiro item da lista, e procura sequencialmente até o

elemento ou o fim da lista serem encontrados.Algoritmo

� Algoritmo de procura linear que encontra ItemProcurado na lista X(1), X(2), …, X(N). À variável Encontrado é atribuído o valor de verdadeiro e a Localizacao é atribuí-da a posição de ItemProcurado quando a procura é bem sucedida; caso contrário Encontrado tem o valor falso.

� Recebe: Lista X(1), X(2), …, X(N) e ItemProcurado.

� Retorna:Se ItemProcurado é encontrado na lista:

Encontrado = verdadeiro, eLocalizacao = posição de ItemProcurado.

Se ItemProcurado não é encontrado na lista:Encontrado = falso (e Localizacao = N + 1)

Page 23: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

23

João Miguel da Costa Sousa 221

Procura linear

� Inicializa Localizacao a 1 e Encontrado a falso.� Enquanto Localizacao <= N e Encontrado é falso:

Se ItemProcurado = X(Localizacao) entãoAtribui a Encontrado o valor verdadeiro.

Caso contrário:Incrementa Localizacao de uma unidade.

� Exemplo: Procura numa cadeia de caracteres. !-Procura_Linear------------------------------------------------------

! Subrotina que procura na lista Item o ItemProcurado usando

! o metodo de procura linear. Se ItemProcurado for encontrado

! na lista, sao retornados: Encontrado com o valor de

! verdadeiro e a Localizacao do item; caso contrario

! Encontrado tem o valor de falso.

!

! Aceita: Tabela Item e ItemProcurado

! Retorna: Se ItemProcurado é encontrado na lista:

! Encontrado = verdadeiro e

! Localizacao = posição de ItemProcurado

! Caso contrario:

! Encontrado = falso

! (Localizacao = ultima posicao examinada)

!-----------------------------------------------------------------------

João Miguel da Costa Sousa 222

Subrotina: Procura_Linear

SUBROUTINE Procura_Linear(Item, ItemProcurado, Encontrado, Localizacao)

CHARACTER(*), DIMENSION(:), INTENT(IN) :: Item

CHARACTER(*), INTENT(IN) :: ItemProcurado

LOGICAL, INTENT(OUT) :: Encontrado

INTEGER, INTENT(OUT) :: Localizacao

INTEGER :: NumeroItems

NumItems = SIZE(Item)

Localizacao = 1

Encontrado = .FALSE.

! Enquanto Localizacao <= NumeroItems e Encontrado falso:

DO

IF ((Localizacao > NumeroItems) .OR. Encontrado) EXIT

! Se fim da lista ou item encontrado, termina procura

! Caso contrario testa o proximo elemento da lista

IF (ItemProcurado == Item(Localizacao)) THEN

Encontrado = .TRUE.

ELSE

Localizacao = Localizacao + 1

END IF

END DO

END SUBROUTINE Procura_Linear

Page 24: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

24

João Miguel da Costa Sousa 223

Procura binária

� Procura que divide lista em 2 sublistas, escolhendo a que tem o item procurado.

� A procura linear requer n comparações, enquanto a procura binária requer log2n.

� Exemplo: lista com 1024 (=210) elementos� Procura binária: máximo 10 comparações.� Procura linear: máximo 1024 comparações.

Algoritmo� Algoritmo de procura binária na lista X(1), X(2), …, X(N) ordenada de forma

ascendente. À variável Encontrado é atribuído o valor de verdadeiro e a Localizacaoé atribuí-da a posição de ItemProcurado quando a procura é bem sucedida; caso contrário Encontrado tem o valor falso.

� Recebe: Lista X(1), X(2), …, X(N) e ItemProcurado.� Retorna:

Se ItemProcurado é encontrado na lista:Encontrado = verdadeiro, eLocalizacao = posição de ItemProcurado.

Se ItemProcurado não é encontrado na lista:Encontrado = falso

João Miguel da Costa Sousa 224

Algoritmo de procura binária

� Inicializa Primeiro a 1 e Ultimo a n. Estes valores repre-sentam as posições do primeiro e do último items da sublista onde a procura está a ser efectuada.

� Inicializa Encontrado com o valor lógico falso. � Enquanto Primeiro <= Ultimo e Encontrado é falso:

� Encontra a posição do meio na sublista, atribuindo a Meio o valor inteiro de (Primeiro + Ultimo) / 2.

� Compara ItemProcurado com X(Meio). Existem três possibilidades:

� ItemProcurado < X(Meio): ItemProcurado está na primeira metade da sublista. Atribui a Ultimo o valor Meio - 1.

� ItemProcurado > X(Meio): ItemProcurado está na segunda metade da sublista. Atribui a Primeiro o valor Meio + 1.

� ItemProcurado = X(Meio): ItemProcurado foi encontrado. Atribui a Localizacao o valor Meio e a Encontrado o valor verdadeiro.

� Exemplo: Procura numa cadeia de caracteres.

Page 25: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

25

João Miguel da Costa Sousa 225

Subrotina: Procura_Binaria

!-Procura_Binaria----------------------------------------------------------

! Subrotina que procura na lista Item o ItemProcurado usando

! o metodo de procura binaria. Se ItemProcurado e encontrado

! na lista sao retornados: Encontrado com o valor de

! verdadeiro e a Localizacao do item; caso contrario

! Encontrado e falso. Esta subrotina e aplicada a cadeias de

! caracteres. Variaveis locais usadas:

! Primeiro : primeiro item a (sub)lista sob procura

! Ultimo : ultimo item a (sub)lista sob procura

! Meio : item do meio na (sub)lista sob procura

!

! Aceita: Tabela Item e ItemProcurado

! Retorna: Se ItemProcurado é encontrado na lista:

! Encontrado = verdadeiro e

! Localizacao = posição de ItemProcurado

! Caso contrario:

! Encontrado = falso

! (e Localizacao = ultima posicao examinada)

!-------------------------------------------------------------------------

SUBROUTINE Procura_Binaria(Item, ItemProcurado, Encontrado, Localizacao)

CHARACTER(*), DIMENSION(:), INTENT(IN) :: Item

CHARACTER(*), INTENT(IN) :: ItemProcurado

LOGICAL, INTENT(OUT) :: Encontrado

INTEGER, INTENT(OUT) :: Localizacao

INTEGER :: Primeiro, Ultimo, Meio

João Miguel da Costa Sousa 226

Subrotina: Procura_Binaria

Primeiro = 1

Ultimo = SIZE(Item)

Encontrado = .FALSE.

! Enquanto Primeiro <= Ultimo e Encontrado falso faz:

DO

IF ((Primeiro > Ultimo) .OR. Encontrado) EXIT

! Se fim da lista ou item encontrado, termina procura

! Caso contrario continua com o seguinte procedimento:

Meio = (Primeiro + Ultimo) / 2

IF (ItemProcurado < Item(Meio)) THEN

Ultimo = Meio - 1

ELSE IF (ItemProcurado > Item(Meio)) THEN

Primeiro = Meio + 1

ELSE

Encontrado = .TRUE.

Localizacao = Meio

END IF

END DO

END SUBROUTINE Procura_Binaria

� Exercício: Desenvolver o mesmo algoritmo de forma recursiva.

Page 26: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

26

João Miguel da Costa Sousa 227

Tabelas multidimensionais

� Tabelas podem ser ordenadas por linhas, colunas, etc. Para isso são necessárias tabelas multi-dimensionais.

� Exemplo: tabela com temperaturas em 3 locais diferentes a 4 horas do dia:

Localização

Tempo 1 2 3

1 65.5 68.7 62.02 68.8 68.9 64.53 70.4 69.4 66.34 68.5 69.1 65.8

� Declaração:

REAL, DIMENSION(4, 3) :: Temperatura

ou:REAL, DIMENSION(1:4, 1:3) :: Temperatura

� reserva 12 espaços em memória para a tabela.Temperatura(2,3)

� refere-se ao elemento da 2ª linha e 3ª coluna.

João Miguel da Costa Sousa 228

Declaração de tabelas genéricas

Declaração de tabelas compiladas_______________________________________________________________________________________________

Forma:

tipo, DIMENSION(l1:u1, l2:u2,..., lk:uk) :: lista_nome_tabelas

outipo :: lista_especificadores_tabelas

� A lista_nome_tabelas é uma lista de nomes de tabelas separadas por vírgulas;

� A lista_especificadores_tabelas é uma lista de especificadores da forma:

nome_tabela(l1:u1, l2:u2,..., lk:uk)

� O número k de dimensões (rank) é no máximo sete.� Cada par l

i:u

ideve ser um parte de constantes inteiras especificando os

limites dos valores do índice i de li

a ui; l

ipode ser omitido se o seu

valor é 1.

Page 27: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

27

João Miguel da Costa Sousa 229

Tabelas n-dimensionais: exemplos

� Cada um dos identificadores da lista é uma tabela k-dimensional, cuja memória é atribuída (alocada) aquando da compilação do programa.

� Exemplos:REAL, DIMENSION(1:2, -1:3) :: Gamma

REAL, DIMENSION(0:2, 0:3, 1:2) :: Beta

INTEGER, DIMENSION(5:12) :: Kappa

ouREAL :: Gamma(1:2,-1:3), Beta(0:2,0:3,1:2)

INTEGER :: Kappa(5:12)

� Tabela Gamma bidimensional 2 × 5, com o primeiro índice de 1 a 2 e o segundo de -1 a 3

� Tabela Beta tridimensional 3 × 4 × 2� Tabela Kappa unidimensional com índices de 5 a 12

João Miguel da Costa Sousa 230

Tabelas n-dimensionais alocáveis

Definição de tabelas alocadas____________________________________________________________________

Forma:

tipo, DIMENSION(:, …,:), ALLOCATABLE :: lista

outipo, DIMENSION(:, …,:) :: lista

ALLOCATABLE :: lista

� A variável lista é uma lista de tabelas;� A dimensão k (rank) é no máximo sete.� Declara que o tamanho de cada uma das tabelas em lista é k-dimensional,

onde k é o número de “:” na especificação de DIMENSION. O número de índices em cada dimensão, chamada a extensão da tabela, será especificado durante a execução.

� Exemplos:REAL, DIMENSION(:, :, :), ALLOCATABLE :: Beta

REAL, DIMENSION(:,:), ALLOCATABLE :: Gamma

Page 28: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

28

João Miguel da Costa Sousa 231

Alocação n-dimensional

Instrução ALLOCATE____________________________________________________________________

Forma:

ALLOCATE(lista)

ouALLOCATE(lista, STAT = estado_variavel)

� A variável lista é dada por:nome_tabela(l

1:u

1, l

2:u

2, …, l

k:u

k)

� Atribui espaço em memória para cada uma das k-dimensionais tabelas da lista. Todas as definições anteriores permancem válidas.

� À variável estado_variavel é atribuído o valor zero se a alocação for bem sucedida. Se não existir mais memória ou a tabela já tiver sido previamente alocada, é atribuído um valor de erro.

� Exemplo:ALLOCATE(Beta(0:2, 0:3, 1:2), Gamma(1:N,-1:3), &

STAT = EstadoAlocacao)

João Miguel da Costa Sousa 232

Entrada/Saída de tabelas

� Processamento elemento a elemento� tabelas unidimensionais: ordem sequencial� tabelas bidimensionais:

�por linha - 1ª linha processada em 1º lugar, seguida pelas linhas seguintes.

� Exemplo: A(1:2, 1:3)A(1, 1)

A(1, 2)

A(1, 3)

A(2, 1)

A(2, 2)

A(2, 3)

�por coluna - 1ª coluna processada em 1º lugar� Exemplo: A(1:2, 1:3)A(1, 1)

A(2, 1)

A(1, 2)

A(2, 2)

A(1, 3)

A(2, 3)

Page 29: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

29

João Miguel da Costa Sousa 233

Entrada/Saída de tabelas (cont.)

�O Fortran processa as tabelas por coluna por defeito (primeiros índices são percorridos primeiro).

�Tabelas multidimensionais: usam ordem por elemento de tabela.

�Tipos de Entrada/Saída com tabelas:� Utilizando um ciclo DO� Utilizando o nome da tabela� Utilizando um DO implícito� Utilizando uma secção da tabela

�E/S com ciclos DO� utilizam-se ciclos DO encadeados

João Miguel da Costa Sousa 234

Exemplo de leitura de tabelas

� Exemplo: ler a tabela A declarada por:INTEGER, DIMENSION(3, 4) :: Tabela

� e que é dada por:

33788948

461001099

25325677

� As instruções seguintes lêem a tabela:DO Linha = 1, 3

DO Coluna = 1, 4

READ (*, *) Tabela(Linha, Coluna)

END DO

END DO

� Lê a primeira linha em primeiro lugar, etc.

Page 30: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

30

João Miguel da Costa Sousa 235

E/S com ciclos DO

� Para ler por colunas:DO Coluna = 1, 4

DO Linha = 1, 3

READ (*, *) Tabela(Linha, Coluna)

END DO

END DO

�E/S utilizando o nome da tabela�Exemplo:READ (*, *) Tabela

� lê por colunas. Se os dados de entrada forem:77, 99, 48, 56, 10, 89

32, 100, 78, 25, 46, 33

� o valor atribuído a Tabela será a matriz dada na página anterior.

João Miguel da Costa Sousa 236

Saída com nome de tabela

� Exemplo escrita:WRITE (*, ‘(1X, 4I5/)’) Tabela

� coloca os elementos por colunas, produzindo a seguinte saída:

77 99 48 56---------------------

---------------------

10 89 32 100---------------------

---------------------

78 25 46 33---------------------

---------------------

� É de notar que a disposição dos elementos é diferente da matriz Tabelaoriginal (pág. 234)!

Page 31: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

31

João Miguel da Costa Sousa 237

Ciclos DO implícitos

� Definição:

(lista, var_controlo = inicial, limite, passo)

� Onde lista corresponde à lista de variáveis de entrada/saída, e var_controlo, inicial, limite e passo são as mesmas variáveis de um ciclo DO.

� Podem ser utilizados ciclos DO implícitos dentro de outros ciclos DOímplicitos.

� Exemplo leitura:READ(*,*) ((Tabela(Linha,Col), Col=1,4), Linha=1,3)

� é equivalente a:READ(*,*) (Tabela(Linha,1),Tabela(Linha,2), &

Tabela(Linha,3),Tabela(Linha,4), Linha=1,3)

� e a:READ(*,*) (Tabela(1,1),Tabela(1,2),Tabela(1,3),Tabela(1,4), &

(Tabela(2,1),Tabela(2,2),Tabela(2,3),Tabela(2,4), &

(Tabela(3,1),Tabela(3,2),Tabela(3,3),Tabela(3,4)

João Miguel da Costa Sousa 238

Ciclos DO implícitos (concl.)

� A leitura por colunas é dada por:READ(*,*) ((Tabela(Linha,Col), Linha=1,3), Col=1,4)

� Uso de parêntesis e vírgulas são importantes para definir os ciclos a executar primeiro.

� READ é executado só uma vez; as variáveis podem ser inseridas numa linha ou várias, é indiferente.

� Escrita com ciclos DO� Combinam-se os DO com os DO ímplicitos

� Exemplo:DO Linha = 1, 3

WRITE(*, ‘(1X, 4I5)’) (Tabela(Linha,Col), Col=1,4)

END DO

� produz:77 56 32 25

---------------------

99 10 100 46---------------------

48 89 78 33---------------------

Page 32: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

32

João Miguel da Costa Sousa 239

Processamento tabelas

� Tabelas constantes� Tabelas unidimensionais podem ser redimensionadas para tabelas

multidimensionais:

RESHAPE(tabela_fonte,forma,preenche,ordem)

� Retorna tabela derivada de tabela_fonte, com a forma especificada, seguida por elemen-tos da tabela preenche, se necessário. A tabela ordem especifica a ordem variação dos índices.

� Argumentos preenche e ordem são opcionais.

� Exemplo 1:A = RESHAPE((/ 11,22,33,44,55,66 /), (/2, 3/))

� ouA = RESHAPE((/ 11*N, N = 1, 6 /), (/2, 3/))

� atribui a A a matriz 2 × 3:

664422

553311

João Miguel da Costa Sousa 240

Tabelas constantes (exemplos)

� Exemplo 2:A = RESHAPE((/ 11,22,33,44,55,66 /), (/2, 3/), &

ORDER = (/2, 1/))

� atribui a A a matriz:

665544

332211

0044

332211

� Exemplo 3:A = RESHAPE((/ 11,22,33,44 /), (/2, 3/), &

PAD = (/0 , 0/), ORDER = (/2, 1/))

� ouA = RESHAPE((/ 11,22,33,44 /), (/2, 3/), &

(/0 , 0/), (/2, 1/))

� atribui a A a matriz:

Page 33: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

33

João Miguel da Costa Sousa 241

Expressões e sub-tabelas

� Expressões com tabelas� Exemplo:

INTEGER, DIMENSION(2,2) :: A,B

� sendo A uma matriz de 2 × 2 dada por:

10

128

11

2515

� a instruçãoB = 2*A + 1

� atribui a B a matriz:

� Sub-tabelas são definidas como:nome_tabela(seccao_sub-indices)

� onde cada item na seccao_sub-indices é um índice, ou um vector de índices.

João Miguel da Costa Sousa 242

Sub-tabelas (exemplos)

� Exemplo:

INTEGER, DIMENSION(2,3) :: A

6655

3322

3322

6655

11 22 33

44 55 66A

=

� Exemplo sub-tabela 1:A(1:2:1, 2:3:1)

A(:, 2:3)

� é a tabela de 2 × 2 dada pelas 2 últimas colunas de A:

� Exemplo sub-tabela 2:A(2, 1:3:1)

A(2, :)

� é a tabela:

� Exemplo sub-tabela 3:A((/ 2, 1 /), 2:3)

[ ]44 55 66

Page 34: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

34

João Miguel da Costa Sousa 243

Atribuição a tabelas n-dimensionais

variavel_tabela = expressao

� onde expressao pode ser:� uma tabela da mesma dimensão� um valor simples

� Exemplo 1:INTEGER, DIMENSION(2,3) :: A

INTEGER, DIMENSION(3,2) :: B

� Instrução 1:A = 0

� retorna:

000

000

00

00

00

� Instrução 2:B = RESHAPE(A, (/3 ,2/))

� retorna a tabela:

João Miguel da Costa Sousa 244

Atribuição a tabelas (exemplos)

� Instrução 3:A(:, 2:3) = RESHAPE((/ I**2, I=1,4) /), (/2,3/))

� muda A para:

1640

910

0.50.100.0

0.00.20.1

2.01.00.0

0.05.00.1

� Exemplo 2:REAL, DIMENSION(2,3) :: Alfa, Beta

� Alfa é dado por:

� Exemplo com a instrução WHERE :WHERE (Alfa /= 0)

Beta = 1.0 / REAL(Alfa)

ELSEWHERE

Beta = 0.0

END WHERE

retorna tabela Beta:

Page 35: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

35

João Miguel da Costa Sousa 245

Funções com tabelas n-dimensionais

� Funções intrínsecas - mais usadas:� ALLOCATED(A)

� MATMUL(A, B)

� MAXVAL(A, D)

� MAXLOC(A)

� MINVAL(A, D)

� MINLOC(A)

� PRODUCT(A, D)

� RESHAPE(A, S, P, O)

� SHAPE(A)

� SUM(A, D)

� SPREAD(A, D, N)

� TRANSPOSE(A)

João Miguel da Costa Sousa 246

Tabelas definidas pelo programador

� Os parâmetros actuais e formais do tipo tabela devem ter o mesmo tipo e formato.

� Existem 3 formas de definir tabelas dentro de subprogramas.

1. Tabela definida explicitamente em dimensão e extensão no subprograma.

2. Subprograma recebe a extensão das dimensões da tabela como argumentos.

3. Tabela recebe uma tabela de dimensões pré-assumidas.

� Estas três formas são extrapolações das definições para tabelas unidimensionais

Page 36: Tabelas unidimensionais - fenix.tecnico.ulisboa.pt · 3 João Miguel da Costa Sousa 181 Tabelas As soluções propostas são ineficientes; é necessária uma estrutura de dados para:

36

João Miguel da Costa Sousa 247

Processamento de matrizes

� Matriz: tabela bidimensional de m × n.� Operações em Fortran são efectuadas elemento a elemento:

� Soma:

A + B

� Subtracção:

A - B

� Multiplicação:

A * B

� A multiplicação uma matriz A de m × n por outra B de n × p, é dada por:

MATMUL(A, B)

� Outras operações como a transposta são dadas por funções intrínsecas.