• Nenhum resultado encontrado

Arrays. IPC2 1999/2000 F. Nunes Ferreira. Acetatos baseados no livro C: How to Program (second edition) H. M. Deitel P. J. Deitel Prentice Hall, 1994

N/A
N/A
Protected

Academic year: 2021

Share "Arrays. IPC2 1999/2000 F. Nunes Ferreira. Acetatos baseados no livro C: How to Program (second edition) H. M. Deitel P. J. Deitel Prentice Hall, 1994"

Copied!
41
0
0

Texto

(1)

IPC2

1999/2000

F. Nunes Ferreira

Acetatos baseados no livro

C: How to Program (second edition)

H. M. Deitel P. J. Deitel

Prentice Hall, 1994

Arrays

(2)

2

u Array é uma estrutura de dados, todos do mesmo tipo. Vectores (1D) e Matrizes (2D, 3D, ...) são exemplos de arrays

u Estrutura/Struct é uma estrutura de dados, os quais podem ser de tipos diferentes

u Ambos os casos são estruturas que, enquanto existem, mantêm o mesmo tamanho.

u Mais tarde, também serão consideradas estruras dinâmicas (listas, filas de espera, pilhas e árvores)

Arrays

Introdução

(3)

3 u

Um array de 6 elementos

c[0] 6 - O primeiro elemento é c[0] ... c[1] 742 c[2] -15 - c[4 + 1] += 2; faz c[5] = 20 c[3] 0 c[4] 32 c[5] 18 u

Declaração

int c[6];

Arrays

Um exemplo

(4)

4

u

Declaração com inicialização

int c[6] = {6, 742, -15, 0, 32, 18};

int n[30] = {9, 45}; /* os 2 primeiros elementos

de n[] são inicializados com 9 e 45,

e os restantes 28 com 0 */

int m[] = {6, 742, -15}; /* cria e inicializa um array com 3 elementos */

Arrays

(5)

5

Arrays

Um exemplo

u Os elementos de um array são inicializados com

c[j] = 10 + 5 * j;

#include <stdio.h> #define SIZE 10 int main(void) { int c[SIZE], j; for (j = 0; j <= SIZE - 1; j++) c[j] = 10 + 5 * j;

printf("%s%10s\n", "Indice", "Valor");

for (j = 0; j <= SIZE - 1; j++) printf("%6d%10d\n", j, c[j]); return 0; } Indice Valor 0 10 1 15 2 20 3 25 4 30 5 35 6 40 7 45 8 50 9 55

(6)

u Numa turma de 40 alunos, foi feito um inquérito à qualidade da comida de uma cantina: 1- má; ... 10- excelente. As

respostas ao inquérito são colocadas num array de 40

elementos e um programa sumariza o resultado numa tabela de 10 entradas #include <stdio.h> #define N_ALUNOS 40 #define NIVEIS 11 int main(void) {

int resposta, nivel;

int respostas[N_ALUNOS] = {5, 6, 4, 8, 4, 10, 8, 4, 5, 4, 5, 2, 5, 1, 5, 7, 3, 5, 9, 5, 7, 6, 6, 5, 5, 3, 6, 7, 6, 8, 2, 5, 7, 6, 4, 3, 9, 5, 3, 7}; int frequencia[NIVEIS] = {0};

for (resposta = 0; resposta <= N_ALUNOS - 1; resposta++) ++frequencia[respostas[resposta]];

printf("%s%10s\n", "Nivel", "Votacao");

for (nivel = 1; nivel <= NIVEIS - 1; nivel++)

printf("%5d%10d\n", nivel, frequencia[nivel]); return 0; } Nivel Votacao 1 1 2 2 3 4 4 5 5 11 6 6 7 5 8 3 9 2 10 1

(7)

7

u Definir o tamanho dos arrays com constantes simbólicas torna os programas mais portáveis

u Utilizar letras maiúsculas para as constantes simbólicas lembra os programadores que estas constantes não variáveis

u Garantir que nenhuma referência a um array se fará para além dos seus limites

Arrays

(8)

8

u Uma cadeia de caracteres (string) é um array de caracteres

u

char experienc1[] = "um";

cria e inicializa um array de comprimento 3, com os caracteres 'u' 'm' e '\0'.

É equivalente a char experienc1[] = {'u', 'm', '\0'};

u Quando se preenche um array de caracteres a partir do teclado, é necessário prever espaço no array até ao primeiro caracter whitespace (ver exemplo seguinte)

Arrays

(9)

u Inicialização de cadeias de caracteres através de uma constante literal e do teclado

#include <stdio.h> int main(void)

{

char cadeia1[20], cadeia2[] = "constante literal"; int i;

printf("Indicar uma cadeia: "); scanf("%s", cadeia1);

printf("cadeia1 e': %s\ncadeia2 e': %s\n", cadeia1, cadeia2);

for (i = 0; cadeia1[i] != '\0'; i++) printf("%c ", cadeia1[i]);

printf("\n"); return 0;

}

Indicar uma cadeia: uma cadeia cadeia1 e': uma

cadeia2 e': constante literal u m a

& não é

(10)

u Arrays estáticos e dinâmicos #include <stdio.h> void iniEstatica(void); void iniDinamica(void); int main(void) { printf("Primeira chamada:\n"); iniEstatica(); iniDinamica(); printf("\n\nSegunda chamada:\n"); iniEstatica(); iniDinamica(); return 0; } void iniEstatica(void) {

static int a[] = {3, 2, 1}; for (i = 0; i <= 2; i++) printf("a[%d] = %d ", i, a[i] += 5); } void iniDinamica(void) { int b[] = {3, 2, 1}; for (i = 0; i <= 2; i++) printf("b[%d] = %d ", i, b[i] += 5); } Primeira chamada:

a[0] = 8 a[1] = 7 a[2] = 6 b[0] = 8 b[1] = 7 b[2] = 6 Segunda chamada:

a[0] = 13 a[1] = 12 a[2] = 11 b[0] = 8 b[1] = 7 b[2] = 6

(11)

11

Arrays

Arrays como argumentos de funções

u C passa arrays completos para funções, simulando uma chamada por referência.

u Boa solução em termos de desempenho

u O nome de um array corresponde ao endereço do seu primeiro elemento, &nome-array[0]

u A especificação de conversão %p é utilizada na visualização de apontadores em hexadecimal

#include <stdio.h> int main(void)

{

char cadeia[5];

printf(" cadeia = %p\n&cadeia[0] = %p\n", cadeia, &cadeia[0]);

return 0; }

cadeia = 0064FDF0 &cadeia[0] = 0064FDF0

(12)

#include <stdio.h> #define TAMANHO 5

void modificArray(int [], int); int main(void)

{

int i, a[5] = {0, 10, 20, 30, 40}; printf("Valores originais:\n");

for (i = 0; i <= TAMANHO - 1; i++) printf("%4d", a[i]);

modificaArray(a, TAMANHO);

printf("\nValores modificados:\n"); for (i = 0; i <= TAMANHO - 1; i++)

printf("%4d", a[i]); return 0;

}

void modificaArray(int x[], int comprimento) {

int j;

for (j = 0; j <= comprimento - 1; j++) x[j] *= 5;

}

• O que resultaria se fosse:

modificaArray(&a[2], TAMANHO - 2);

Valores originais: 0 10 20 30 40 Valores modificados: 0 50 100 150 200

(13)

13

Arrays

Qualificador const aplicado a arrays

u Qualificador const utilizado para evitar alterações (não desejadas) de arrays dentro de funções

void tentaModificar(const int []); int main(void) { int a[] = {10, 20, 30}; tentaModificar(a); . . . return 0; }

void tentaModificar(const int b[]) {

b[0] *= 10; b[1] *= 20; b[2] *= 30; }

• Desempenho da referência, segurança da passagem por valor

Erros de compilação, por tentativa de modificar constantes ! . . .

(14)

14

Arrays

Ordenação - bubble sort

u O array vai ser percorrido tantas vezes quantos os seus elementos menos 1.

Em cada percurso o maior valor encontrado é puxado para o final... ... Vai comparando pares de valores ... ... e trocando-os entre si, se necessário

u Pouco eficiente, mas fácil de programar

1 2 3 4 5 6 7 8 9 Valores originais: 5 1 7 3 2 4 0 9 8 6 Valores em ordenacao: 1 5 3 2 4 0 7 8 6 9 1 3 2 4 0 5 7 6 8 9 1 2 3 0 4 5 6 7 8 9 1 2 0 3 4 5 6 7 8 9 1 0 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

(15)

#include <stdio.h> #define TAMANHO 10 int main(void)

{

int i, passo, temp;

int array[TAMANHO] = {5, 1, 7, 3, 2, 4, 0, 9, 8, 6}; printf("Valores originais:\n");

for (i = 0; i <= TAMANHO - 1; i++) printf("%3d", array[i]);

printf("\nValores em ordenacao:\n");

for (passo = 1; passo <= TAMANHO - 1; passo++){ for (i = 0; i <= TAMANHO - 2; i++)

if (array[i] > array[i + 1]){ temp = array[i];

array[i] = array[i + 1]; array[i + 1] = temp;

}

for (i = 0; i <= TAMANHO - 1; i++) printf("%3d", array[i]); printf("\n"); } return 0; } 5 1 7 3 2 4 0 9 8 65 1 7 3 2 4 0 9 8 6

(16)

16

Arrays

Ordenação - bubble sort

u Uma versão em que o bubble sort só trata da ordenação

#include <stdio.h> #define DIM_MAX 100 #define N_COL 6

int leVector(int vec[], int dim);

void visuVector(const int vec[], int dim, int nCol); void bubleSort(int vec[], int dim);

int main(void) {

...

- ler nº inteiros a ordenar - ler vector

- visualizar vector a ordenar -

ordenar vector

(17)

int main(void) {

int valores[DIM_MAX], num; do {

printf("\nNumero valores (< %d):\n", DIM_MAX); scanf("%d", &num);

} while (num < 1 || num > 100);

printf("\nLeitura dos elementos do vector:"); leVector(valores, num);

printf("\n\nVector a ordenar:\n"); visuVector(valores, num, N_COL); bubleSort(valores, num);

printf("\nVector ordenado:\n"); visuVector(valores, num, N_COL); return 0;

(18)

int leVector(int vec[], int dim) {

int i;

for(i = 0; i < dim; i++) { printf("\nInteiro: "); scanf("%d", &vec[i]); } return i; }

void visuVector(const int vec[], int dim, int nCol) {

int i, c;

for (i = 0; i <= dim - 1; i++) {

putchar(c = (i % nCol == 0) ? '\n' : ' '); printf("%6d", vec[i]);

} }

(19)

19

• Recebe um vector de inteiros e devolve-o

ordenado

void bubleSort(int vec[], int dim)

{

int passo, i, temp;

for (passo = 1; passo <= dim - 1; passo++)

for (i = 0; i <= dim - 2; i++)

if (vec[i] > vec[i + 1]){

temp = vec[i];

vec[i] = vec[i + 1];

vec[i + 1] = temp;

}

}

Arrays

(20)

20

u Pesquisa linear (arrays pequenos e não necessariamente ordenados)...

u Pesquisa binária (arrays grandes e necessariamente ordenados)...

u O programa cria um array com valores inteiros (vamos supor que são apenas inteiros pares) e responde da seguinte maneira:

u Função a usar...

const

int procuraLin( int a[], int valor, int tamanho)

Indicar o valor inteiro a procurar: 36 Valor encontrado na posicao 18

Indicar o valor inteiro a procurar: 37 Valor nao encontrado

Arrays

(21)

#include <stdio.h> #define SIZE 10

int procuraLin (int [], int, int); int main(void)

{

int a[SIZE], i, valor, indice;

/* criar um array de inteiros */ for (i = 0; i < SIZE; i++)

a[i] = 2 * i;

printf("Valor a procurar: "); scanf("%d", &valor);

indice = procuraLin(a, valor, SIZE);

if (indice == -1)

printf("Valor nao encontrado\n"); else

printf("Valor encontrado na posicao de indice %d\n", indice); return 0;

(22)

int procuraLin (int a[], int valorProcurado,

int comprimento)

{

int i;

for (i = 0; i < comprimento; i++)

if (a[i] == valorProcurado)

return i;

return -1;

}

(23)

23

u Idêntido ao anterior, mas com pesquisa binária

int procBin(const int quad[], int valor, int indInf, int indSup)

Indicar um valor entre 0 e 28: 25

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 2 4 6 8 10 12 14* 16 18 20 22 24 26 28 16 18 20 22* 24 26 28 24 26* 28 24*

25 nao foi encontrado

Indicar um valor entre 0 e 28: 6

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0 2 4 6 8 10 12 14* 16 18 20 22 24 26 28 0 2 4 6* 8 10 12

6 foi encontrado na posicao 3

Arrays

Exercício: pesquisa binária

índice vector

(24)

24

Arrays

arrays multidimensionais

u Array bidimensional: int q [3][4]

Coluna Coluna Coluna Coluna

0 1 2 3

Linha 0 q[0][0] q[0][1] q[0][2] q[0][3] Linha 1 q[1][0] q[1][1] q[1][2] q[1][3] Linha 2 q[2][0] q[2][1] q[2][2] q[2][3]

u array de 3 linha e 4 colunas: array 3 x 4

ou

u array de 3 elementos, sendo cada um deles um array de 4 elementos (inteiros)

u Exemplo, q[1] corresponde a um array de 4 inteiros

(25)

25

Arrays

arrays multidimensionais

u Para percorrer um array (linha a linha, coluna ...) soma = 0;

for (linha = 0; linha <= 2; linha++)

for (coluna = 0; coluna <= 3; coluna++) soma += q[linha][coluna]; u

Inicialização

int a[2][3] = {{1, 2, 3},{4, 5, 6}}; a: 1 2 3 4 5 6 int b[2][3] = {1, 2, 3, 4, 5}; b: 1 2 3 4 5 0 int c[2][3] = {{1, 2}, {4}}; c: 1 2 0 4 0 0

(26)

26

Exercícios

Simulação de um helicóptero digital - 1

u

Um helicóptero imaginário é comandado

através do teclado. O helicóptero, quando no

ar, não deixa rasto. Para deixar rasto

deverá estar em contacto com o terreno.

Comando Efeito

1 Põe o helicóptero no ar

2 Põe o helicóptero em contacto com o terreno 3 Faz o helicóptero rodar 90o para a direita

4 Faz o helicóptero rodar 90o para a esquerda 5 d Desloca o helicóptero (pelo ar ou em

contacto com o terreno) d posições para a frente 6 Visualiza o terreno (com os rastos feitos

pelo helicóptero)

7 Limpa os rastos do helicóptero no terreno 9 Termina o programa

(27)

27

Exercícios

Simulação de um helicóptero digital - 2

u O terreno é suposto ser um quadrado de dimensão 20 x 20, a que corresponde 20 x 20 células, cada uma

identificada pela linha e coluna respectivas. O

helicóptero é caracterizado pela sua posicao, dada pela linha e coluna onde se encontra (não

necessariamente uma linha e uma coluna do terreno, pois o helicóptero pode deslocar-se para fora dos limites daquele), e é ainda caracterizado pela sua orientacao (um dos pontos cardeais: N, S, E ou O) e situacao (no ar ou no plano do terreno).

linha 20 --- Helicóptero --- posição: 16 11 --- situação: terreno ---H--- orientação: N ... linha 1

---N

(28)

28

Exercícios

Simulação de um helicóptero digital - 3

u O helicóptero é visualizado pela letra H, as células ainda não visistadas por ele são visualizadas com -, enquanto que as já visitadas serão representadas por O. Por exemplo, após o comando 5 com d=2, obtém-se: linha 20

--- Helicóptero

---H--- posição: 18 11 ---O--- situação: terreno ---O--- orientação: N

...

linha 1

---• Exemplo de uma sessão com o programa

helicoptero-digital, em que as condições iniciais correspondem a terreno limpo e o helicóptero com posicao: 16 11;

(29)

29

Exercícios

Simulação de um helicóptero digital - 4

u Comando: 3 ; roda para a direita 90o

u Comando: 5 ; avança

u Posicoes em frente: 3 ; 3 posições

u Comando: 4 ; roda para a esquerda 90o

u Comando: 5 ; ... u Posicoes em frente: 2 u Comando: 4 u Comando: 5 u Posicoes em frente: 6 u Comando: 6 linha 20 ... linha 1

(30)

---30

Exercícios

Simulação de um helicóptero digital - 5

u 1- Definir e implementar, se necessário, uma abstracção de dados compatível com o problema exposto.

u 2- Fazer uma abordagem de-cima-para-baixo ao

programa helicoptero-digital, para identificar as suas tarefas e sub-tarefas principais.

u 3- Escrever em C o programa helicoptero-digital, tomando por base os resultados da abordagem

anterior.

u Nota:

O helicóptero na sua deslocação pode ultrapassar os limites do terreno, situação em que não deixa rasto. O programa continuará a actualizar as suas

características, de acordo com os comandos que vai recebendo.

(31)

31

Exercícios

Bubble sort

u

A ordenação bubble sort já apresentada é

extremamente ineficiente para arrays de

grandes dimensões. Introduzir os seguintes

melhoramentos àquela solução.

1- Depois do 1º passo é garantido que o maior

valor está na última posição, que não

necessitará de ser visitada no passo

seguinte...

2- O array a ordenar pode já estar próximo da

ordenação pretendida, não sendo necessários

todos os passos. Basta detectar quando, num

dado passo, não se verifique qualquer

(32)

32

• Recebe um vector de inteiros e devolve-o

ordenado

void bubleSort(int vec[], int dim)

{

int passo, i, temp;

for (passo = 1; passo <= dim - 1; passo++)

for (i = 0; i <= dim - 2; i++)

if (vec[i] > vec[i + 1]){

temp = vec[i];

vec[i] = vec[i + 1];

vec[i + 1] = temp;

}

}

Arrays

(33)

33

Exercícios

Bucket Sort - 1

u Um array contém n inteiros positivos para ordenar. Considerar um array auxiliar 10 x n. Cada uma das suas 10 linhas é designada por bucket. Escrever a função bucketSort que toma um array de inteiros e o seu comprimento como argumentos e implementa o

seguinte algoritmo:

1- Percorre o array e coloca os seus elementos nas linhas do array 10 x n, de acordo com o seu dígito das unidades. Por exemplo, 97 é colocado na linha 7, 3 é colocado na linha 3, e 100 na linha 0.

2- Percorre o array auxiliar e obtém o array inicial agora ordenado da seguinte maneira: 100, 3, 97. 3- Repete 1- e 2- agora com o dígito das dezenas,

depois das centenas, ... e termina quando é tratado o dígito mais significativo do maior número.

(34)

34

Exercícios

Bucket Sort - 2

Array a 10 buckets ordenar B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 97 3 100 100 3 97 100 3 97 100 97 3 100 3 97 3 100 97

3 97 100 <--- termina, pois não há mais dígitos... Se continuasse, cairiam todos em B0.

(35)

35

u

O algoritmo Selection sort inicia-se

procurando o elemento mais pequeno de um

array. Esse elemento é trocado com o primeiro

elemento do array. O processo continua com o

sub-array constituido a partir do segundo

elemento do array...

O processo termina quando o sub-array tem

apenas um elemento.

Escrever uma função recursiva para este

algoritmo.

Exercícios

Selection sort

(36)

36

u Foi apresentado um exemplo relativo à procura linear (para arrays pequenos e com os respectivos elementos

não ordenados). Escrever agora uma função recursiva que faz a mesma pesquisa e recebe como argumentos um array de inteiros, um inteiro que é o valor a procurar e um inteiro que é o tamanho daquele array. Se o valor é

encontrado, a função devolve a sua posição. Se não for encontrado, devolve -1.

u Também foi apresentado um exemplo relativo à procura binária (para arrays grandes e com os respectivos

elementos ordenados). Escrever a função recursiva que faz a mesma pesquisa e recebe como argumentos um array de inteiros, um inteiro que é o valor a procurar, e

dois inteiros que representam, respectivamente, o índice mais baixo e o índice mais alto do array a

pesquisar. Se o valor é encontrado, a função devolve a sua posição. Caso não seja encontrado, devolve -1.

Exercícios

(37)

37

u

Escrever a função recursiva visuArray que

toma um array e o seu tamanho como argumentos

e não devolve nada. A função visualiza os

elementos do array e pára quando recebe um

array de tamanho zero.

u

Escrever a função recursiva

visuCadeiaAoContrario que toma um array de

caracteres como argumento e visualiza a

cadeia ao contrário, com um espaço entre

caracteres. A função pára quando encontra o

caracter nulo, '\0'.

Exercícios

Recursividade

(38)

#include <stdio.h>

void visuCadeiaAoContrario(char []); int main(void)

{

char cadeia[] = "123abcdfgh";

printf("\nCadeia original: %s\n", cadeia); printf("\nCadeia ao contrario: "); if ('\0' != cadeia[0]) visuCadeiaAoContrario(cadeia); printf("\n"); return 0; }

void visuCadeiaAoContrario(char cadeia[]) { if ('\0' == cadeia[1]) printf("%c ", cadeia[0]); else { visuCadeiaAoContrario(&cadeia[1]); printf("%c ", cadeia[0]); } }

(39)

39

u

Escrever a função recursiva minNoarray que

toma um array de inteiros e um inteiro que é

o seu tamanho como argumentos e devolve o

mais pequeno valor no array. A função pára

quando recebe um array com um valor.

u

Escrever a função recursiva capicua que toma

uma cadeia de caracteres como argumento e

devolve 1 se essa cadeia for uma capicua ou

zero, se não for capicua.

Exercícios

Recursividade

(40)

#include <stdio.h> #define TAMANHO 10

int minNoarray(int [], int); int main(void)

{

int i;

int array[TAMANHO] = {9, 8, 7, 6, -5, 4, 0, 2, 1, 78}; printf("\nValores originais:\n");

for (i = 0; i <= TAMANHO - 1; i++) printf("%3d", array[i]);

printf("\nValor minimo: %d\n", minNoarray(array, TAMANHO)); return 0;

}

int minNoarray(int quad[], int tamanho) {

int valorMin;

if (1 == tamanho) return quad[0]; else{

valorMin = minNoarray(&quad[1], --tamanho); return

quad[0] < valorMin? quad[0]: valorMin; }

(41)

#include <stdio.h> #include <string.h> int capicua(char []);

int capicuaAux(char [], size_t); int main(void)

{

char cadeia[] = "abc d cba";

printf("\nCadeia original: %s\n", cadeia); if (capicua(cadeia))

printf("E uma capicua\n"); else

printf("Nao e uma capicua\n"); return 0;

}

int capicua(char cadeia[]) {

return capicuaAux(cadeia, strlen(cadeia)); }

int capicuaAux(char cadeia[], size_t comp) {

if (comp == 0 || comp == 1) return 1;

else

return cadeia[0] == cadeia[comp - 1] && capicuaAux(&cadeia[1], comp - 2); }

Referências

Documentos relacionados

Associations between chewing pattern, presence of atypical contractions in mastication and deglutition, presence of noise and standard mouth opening were analyzed.. There was

E, para o manter bem informado, o Novo Nissan X-Trail emprega um sistema avançado que pode efectivamente ler os sinais de trânsito, incluindo os limites de velocidade e outros

O órgão público que desejar fazer uso dos certificados Cert-JUS, deve autorizar a emissão para cada titular, equipamento ou aplicação e é responsável pelo fornecimento

(2002), afirmam que as organizações devem conceber e utilizar processos formais de geração, refinamento e avaliação de ideias, assim como de Sistemas de Gestão de Ideias

A ECAR não assumirá responsabilidade alguma em relação ao uso dos Certificados emitidos por esta e o par de chaves privada/pública associado aos seus titulares

No Brasil, estão registradas 19 espécies com ocorrência nos domínios da Amazônia, Caatinga, Cerrado e Floresta Atlântica, três delas no Nordeste, sendo duas em Pernambuco

data de postagem dentro do prazo referido no subitem anterior, para: Seção Técnica de Desenvolvimento e Administração de Recursos Humanos do Câmpus de Dracena (Ref: Recurso em

Convencionam as partes que, exclusivamente para os empregados que mantêm contrato de trabalho com a mesma empresa ou, empresa do mesmo grupo econômico há mais de 10 (dez) anos e