Cursos: Análise, Ciência da Computação e Sistemas de Informação Programação I - Prof. Aníbal Lista de exercícios 8 Exercícios com arrays unidimensionais 1. Complete a figura de acordo com os valores gerados pelos comandos abaixo: int[] x = new int[10]; int[] y = new int[10]; int[] z = new int[10]; for (int i = 0; i < 9; i++){ x[i] = i; y[i] = x[i]++; z[i] = x[i] + y[i]; z[i + 1] = ++z[i]; } int[] x int[] y 0 1 2 3 4 5 6 7 8 9 int[] z 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 2. Para cada conjunto de valores abaixo, escreva o código Java, usando laço(s), que preencha um array com os valores: a) 10 9 8 7 6 5 4 3 2 1 b) 0 1 4 9 16 25 36 49 64 81 100 c) 1 2 3 4 5 10 20 30 40 50 d) 3 4 7 12 19 28 39 52 67 84 3. Escreva um trecho Java que exiba os valores de um array a double numa mesma linha. 4. Escreva um trecho Java que leia 10 valores double do teclado e armazene-os num array d. 5. Abaixo aparece parte do código fonte da classe Circulo public class Circulo{ private double raio, area; public Circulo(double r){raio = r;} public void calculaArea(){area = Math.PI * Math.pow(raio, 2);} public double getRaio(){return raio;} public double getArea(){return area;} } Programação I - Prof. Aníbal - Lista de Exercícios 8 1 a) Desenhe um diagrama da memória após a execução do seguinte trecho de uma classe de teste: Circulo[] c = new Circulo[3]; c[2] = new Circulo(4.5); c[1] = new Circulo(8); b) Continue o trecho de código do item (a) de acordo com os comentários: /** Instancie outro objeto Circulo, com raio lido do teclado, e atribua seu endereço à posição 0 do array c */ /** Usando um laço de repetição, calcule e exiba na tela a área de cada circulo do array c */ 6. Crie um método que recebe um array de inteiros e retorna a quantidade de elementos do array que são números negativos. 7. Crie um método que recebe um array de objetos do tipo Circulo e retorna o valor do maior raio. Considere que nenhuma posição do array é null. 8. Programe em Java a classe Estudante com os seguintes membros: Atributos privados: - nome do estudante - um array de notas tipo double Construtor: um só, que recebe o nome do estudante e dimensiona o array de notas em 5. Métodos: + insereNotas – permite ler do teclado as cinco notas do estudante e as atribui às cinco posições do array. + calculaMedia – devolve o valor da média aritmética das notas do estudante + métodos get – são dois. O método get para as notas devolve o array de notas + menorNota – devolve o valor da menor nota do estudante 9. Desenhe o diagrama da memória após a execução das duas linhas de código abaixo, pertencentes a uma classe de teste. A classe Estudante é a do ex.anterior. As notas inseridas são 4.6, 10, 6.5, 8 e 7.4: Estudante e = new Estudante(“Camões”); e.insereNotas(); 10. Escreva um método que recebe um array de números e devolve a posição onde se encontra o maior valor do array. Se houver mais de um valor maior, devolver a posição da primeira ocorrência. 11. Programe um método que recebe um array de objetos do tipo Circulo e um valor double. O método vai procurar no array um objeto que tenha como raio o valor passado no parâmetro. Se encontrar só na primeira metade do array, vai retornar 1; só na segunda metade, vai retornar 2; se aparecer na primeira e na segunda metade, retornará 3; se não achar, vai retornar 0. A classe Circulo está descrita no ex. 5. 12. Faça um método que devolve um array de números lidos do teclado. Recebe a quantidade de números a serem lidos. 13. Programe em Java um método que recebe via parâmetro um array de objetos Estudante, calcula a média de todos eles e devolve um outro array de objetos Estudante contendo apenas aqueles que foram aprovados, sabendo que 6 é a média mínima para aprovação. Se nenhum estudante foi aprovado, retornar null. A classe Estudante está descrita no exercício 8. 14. Crie um método que recebe um array de inteiros positivos e substitui seus elementos de valor ímpar por -1 e os pares por +1. Programação I - Prof. Aníbal - Lista de Exercícios 8 2 15. Complete o método abaixo que deve trocar os valores das posições i e j entre si, dentro do array c. Este método poderá ser chamado sempre que for necessário permutar os conteúdos de duas posições quaisquer de um array de inteiros. public void troca(int[] c, int i, int j){........} 16. Crie um método que recebe um array de inteiros e troca o primeiro elemento com o segundo, o terceiro com o quarto, e assim por diante. Chame o método troca do exercício anterior, quando necessário. 17. Idem ao ex. anterior, trocando o primeiro elemento com o último, o segundo com o penúltimo, e assim por diante. 18. Complete o método abaixo para ordenar o array aluno em ordem alfabética de nome. public void ordenaAlfabeticamente(Estudante[] aluno){ ... } 19. Acrescente uma sobrecarga ao método calculaMedia da classe Estudante, que deverá retornar o valor da média ponderada do objeto estudante. Para isso, recebe através de parâmetro um array de cinco inteiros que são os pesos respectivos de cada uma das cinco notas. 20. Crie uma classe Urna com dois atributos: número da urna e um array unidimensional inteiro que deverá conter a contagem de votos de cada candidato, segundo seu número. Os candidatos são numerados sequencialmente a partir de 1. Se são 3 candidatos, seus números são 1, 2 e 3. A posição 0 do array deve contar os votos nulos. Um voto é nulo se algum eleitor informa um número diferente dos números válidos para os candidatos. Crie os seguintes construtor e métodos: o construtor deve receber, como parâmetros, o número da urna e a quantidade de candidatos (cuide para inicializar o array deixando a posição 0 para a contagem de nulos); método recebeVoto(int candidato) que deve contar mais um voto para o candidato ou para os nulos; método exibeResultado( ) mostra na tela a votação recebida por cada candidato, quantos votos nulos e o total de votos, no seguinte formato: Resultado da eleição Candidato 1 2 3 ... nulos Total de votos: Votação xxx xxx xxx .... xxx xxxx 21. Acrescente um método à classe Data (criada na lista de exercícios 3) que devolva uma data na forma de um String, com o mês por extenso, como, por exemplo, 23 de maio de 2011.. Use um array auxiliar de tipo String para armazenar os nomes dos meses. 22. Crie uma classe Vendedor, com dois atributos: nome e um array de 12 posições, que deverá acumular, em cada posição, a soma das vendas feitas pelo vendedor no respectivo mês (é um array de 12 acumuladores). Crie um construtor e os seguintes métodos: + getNome + vende - recebe o número do mês em que a venda aconteceu e o valor da venda, e acumula na respectiva posição do array; + totalizaVendasAno – devolve a soma do array + resumeVendasAno – devolve um String com o total de vendas de cada mês e o total vendido no ano, no seguinte formato: Programação I - Prof. Aníbal - Lista de Exercícios 8 3 Vendas do ano do vendedor xxxxxxxxxxxxxxx ←aqui aparece o nome do vendedor Janeiro Fevereiro Março ..... Dezembro xxxxx.xx xxxxx.xx xxxxx.xx Total do ano xxxxx.xx xxxxx.xx 23. Um teatro possui três categorias de poltronas para seus espetáculos, os quais diferem em preço e localização dentro da sala: Plateia baixa, com 250 lugares, tem sempre o preço de ingresso mais caro do teatro. Plateia alta, com 278 lugares – cada ingresso nesta localidade custa 75% do ingresso na plateia baixa. Mezanino, com 248 lugares – é a localidade de ingresso mais barato (55% do ingresso na platéia baixa). Programe a classe Espetaculo em Java, onde cada objeto representa uma sessão de alguma apresentação no teatro e serve para controlar a venda de ingressos. Atributos privados: - nome do espetáculo; - plateiaBaixa – array de inteiros – cada posição, a partir da 1, representa um lugar na plateia baixa cujo número corresponde ao índice. Ao ser vendido, aquela posição recebe o número do ingresso correspondente; - plateiaAlta – idem para lugares da plateia alta; - mezanino – idem para lugares no mezanino; - total arrecadado com a venda de ingressos - preço do ingresso na plateia baixa - número do último ingresso vendido – os ingressos são numerados sequencialmente a partir de um certo número. Construtor: recebe o nome do espetáculo, o valor do ingresso para plateia baixa e o número do primeiro ingresso. Deve inicializar adequadamente os atributos, sendo que os arrays devem ser dimensionados aqui. Métodos: + bloqueiaLugar – recebe um inteiro indicando o tipo de localidade (1 – plateia baixa; 2 – plateia alta; 3 – mezanino) e o número do lugar e o bloqueia, ou seja, marca com o valor -1. Isto indicará que aquele lugar não pode ser vendido pois está reservado para algum convidado especial. + isLotada - recebe uma localidade e retorna true se ela estiver lotada; false, em caso contrário. + vendeIngresso - chamado cada vez que alguém quer comprar um ingresso para o espetáculo. Usa teclado para entrar com dados. Inicialmente mostra os lugares disponíveis para venda, separados por localidade e com o preço de cada localidade indicado. O usuário escolhe, então, a localidade e o lugar. O número do ingresso vendido deve ser anotado na posição do array a que corresponde o lugar comprado. Atualizar outros atributos necessários. +gets + o aluno pode fazer outros métodos que julgar necessários 24. Escreva um método que gera e devolve um array com 50 inteiros randômicos tirados do intervalo [1, 100], sem repetições de valores. Programação I - Prof. Aníbal - Lista de Exercícios 8 4 25. Responda bom base no diagrama e no código Java: A[] a = new A[5]; a[0] = new C(); a[1] = new A(); a[2] = new B(); a[4] = new C(); A +m1() +m3() B +m1() +m2() C +m2() +m4() a[i].m1();acionará o método m1 de A para i = ____________ a[i].m1();acionará o método m1 de B para i = ____________ a[i].m3();acionará o método m3 de A para i = ____________ a[i].m4();acionará o método m4 de C para i = ____________ a[i].m2();acionará o método m2 de C para i = ____________ a[3].m1();causará___________________________________ if(a[i] instanceof B) ((B)a[i]).m2();acionará o m2 de B para i = ___________ 26. Dado o seguinte código Java: public class A{ public void m1(int n) {System.out.println(n);} public void m2(int n) {System.out.println(n*2);} } public class B extends A{ public void m1(int n) {System.out.println(n*10);} public void m2(int n) {System.out.println(n*2 * 10);} } public class C extends A{ public void m1(int n) {System.out.println(n*100);} public void m2(int n) {System.out.println(n*2*100);} } public class Teste{ public static void main(String args[]){ A a[] = new A[3]; a[0] = new A(); a[1] = new B(); a[2] = new C(); for (int i = 0; i <3; i++){ a[i].m1(i); a[i].m2(i); } } } a) Desenhe um diagrama UML envolvendo as classes A, B e C b) O que será impresso pela classe Teste c) Inclua o método public void m3(int n){System.out.println(n*3);} na classe B, e ajuste a classe Teste no que for necessário para chamar o método m3 dentro do for sem causar erro. 27. Os alunos de uma escola podem ter uma quantidade variável de notas até um máximo estabelecido pela escola. Assim, supondo que o máximo é 6 notas, o aluno pode preferir não realizar todas as avaliações, mas somente algumas. Por exemplo, se ele optar por 3 avaliações apenas, terá 3 notas e a média será feita somente sobre estas 3 notas. Programe a classe aluno com os seguintes membros: Atributos privados: - nome do aluno; - um array de notas - ele vai sendo preenchido a partir do seu início, registrando cada nota do aluno (poderá não ser preenchido totalmente, dependendo da vontade do aluno) - um contador para indicar quantas notas já foram lançadas no array de notas; Construtor: recebe o nome do aluno e o número máximo de notas permitidas. Instancia o array de notas e zera o atributo contador, além de inicializar o atributo nome. Programação I - Prof. Aníbal - Lista de Exercícios 8 5 Métodos: + insereNota – recebe o valor de uma nota e, se o array de notas ainda não está cheio, insere-a na próxima posição disponível, atualizando, também, o atributo contador. + calculaMedia – retorna a média do aluno que deve ser calculada respeitando o que foi explicado no início do enunciado. + exibeNotas - exibe as notas que aluno tem no momento. Veja solução comentada deste exercício no final da lista. 28. Na lista 7, ex.8, você estendeu a classe Funcionário, criando uma subclasse Programador. Altere o que for necessário na classe Programador, para permitir o registro não apenas de uma linguagem de programação da preferência do programador, mas de até 10 linguagens. Substitua o atributo que armazena a linguagem de preferência por um array com capacidade de até 10 linguagens. Trata-se de um array preenchido parcialmente, pois um programador pode ter menos de 10 linguagens de sua preferência (o que, aliás, corresponde à realidade). 29. Dê continuidade à pequena aplicação bancária do exercício 18 da lista 7, criando uma classe Correntista com os seguintes Atributos: - nome do correntista; - um array de objetos do tipo ContaBancaria, que corresponde às várias contas que um correntista pode ter, sabendo que este Banco limita a um máximo de 10 contas por correntista. Trata-se, portanto, de um array de length = 10, mas que pode ser preenchido parcialmente. Cabe ao aluno definir como irá controlar isso. Construtor: recebe como parâmetro apenas o nome do correntista e inicializa todos os atributos convenientemente (quando um correntista é instanciado ele não teve ainda nenhuma conta aberta). Métodos: abreConta – recebe um objeto do tipo ContaBancaria e insere-o na próxima posição livre do atributo array de contas – o método retorna true se a operação teve sucesso, e false caso a quantidade máxima de contas já tenha sido atingida antes. somaSaldos – devolve a soma dos saldos de todas as contas do correntista contaDeMaiorSaldo – devolve o objeto do tipo ContaBancaria que representa a conta do correntista que possui o maior saldo no momento ordenaContas - devolve um array das contas que o correntista realmente possui no momento, ordenado por ordem crescente de saldo. métodos get. Programação I - Prof. Aníbal - Lista de Exercícios 8 6 Algumas respostas 1. x: 1 2 3 4 5 6 7 8 9 0 y: 0 1 2 3 4 5 6 7 8 0 z: 2 4 6 8 10 12 14 16 18 18 2. d) int a[] = new int[10]; for (int i = 0; i<a.length; i++) a[i] = Math.pow(i, 2) + 3; 5. a) c Circulo[ ] 0 1 2 null Circulo raio 8.0 área 0.0 Circulo raio 4.5 área 0.0 9. e Estudante nome String Camões nota double[] 0 1 2 3 4 4.6 10.0 6.5 8.0 7.4 13. public Estudante[] selecionaAprovados (Estudante[] e){ int ap = 0; //vai contar estudantes aprovados, para dimensionar o novo array for (int i = 0; i < e.length; i++){ e[i].calculaMedia; if (e[i].getMedia() > 6) ap++; } if (ap == 0) return null; else{ Estudante[] e1 = new Estudante[ap]; int k = 0; Programação I - Prof. Aníbal - Lista de Exercícios 8 7 for (int i = 0; i < e.length; i++) if (e[i].getMedia() > 6) e1[k++] = e[i]; return e1; } } 22. import java.text.DecimalFormat; // permite formatar numeros decimais public class Vendedor{ private static final String[] MES = {"Janeiro "Abril ","Maio ","Junho ","Julho "Outubro ","Novembro ","Dezembro "}; private String nome; private double[] vendasPorMes; ","Fevereiro","Marco ", ","Agosto ","Setembro ", public Vendedor(String n){ nome = n; vendasPorMes = new double[12]; } public String getNome(){return nome;} public void vende(int mesDaVenda, double valor){ vendasPorMes[mesDaVenda -1] += valor; } public double somaVendasAno(){ double soma = 0; for (int i = 0; i<vendasPorMes.length; i++) soma += vendasPorMes[i]; return soma; } public String resumeVendasAno(){ double soma = 0; DecimalFormat emReais = new DecimalFormat("R$ ###,##0.00"); String s = "Vendas do ano do vendedor " + getNome() + "\n\n"; for (int i=0; i<vendasPorMes.length; i++) s += MES[i] + "\t " + emReais.format(vendasPorMes[i]) + "\n"; s += "\nTotal do ano " + emReais.format(somaVendasAno()); return s; } } 27. Solução comentada Este exercício exemplifica o uso de um array, que é uma coleção de tamanho fixo, simulando uma coleção de tamanho variável. Assim, além do length, que é o tamanho fixo do array, que corresponde à área reservada na memória para o seu armazenamento, existe um outro tamanho a ser controlado pelo programa, que é a quantidade realmente utilizada dessa área física. Chamamos o length de tamanho físico, e o outro de tamanho lógico. Por outro lado, pressupõe-se que o array seja preenchido gradualmente a partir de seu início e não de forma aleatória. Programação I - Prof. Aníbal - Lista de Exercícios 8 8 public class Aluno{ private String nome; private double[] nota; private int quantidadeDeNotas; //contador – indica quantas posições do array //já foram ocupadas – dizemos que é o tamanho lógico public Aluno (int maxNotas){ nota = new double[maxNotas]; //cria o array para um máximo de notas quantidadeDeNotas = 0; //por enquanto, nenhuma nota foi inserida } public void insereNota(double n){ if (quantidadeDeNotas < nota.length) nota[quantidadeDeNotas++] = n; } public double calculaMedia(){ double soma = 0; if (quantidadeDeNotas == 0) return 0; for (int i = 0; i < quantidadeDeNotas; i++)//o for não vai até length soma += nota[i]; return soma/quantidadeDeNotas; } public void exibeDados(){ System.out.println(“Aluno: “ + nome + “Notas: “); for (int i = 0; i < quantidadeDeNotas; i++) System.out.println(nota[i]); System.out.println(“Média: “ + calculaMedia()); } } O array é uma coleção de tamanho fixo, isto é, após instanciado não pode ter seu length alterado. Daí porque o atributo length é só de leitura. Ao simular uma coleção de tamanho variável, que pode aumentar ou diminuir seu tamanho ao longo do tempo, o contador tem papel importante porque é ele que controla a porção real do array que está valendo. Ele exerce a função de tamanho lógico, já que o tamanho físico (o lenght), neste caso não corresponde à realidade do problema. A figura abaixo ilustra tal ideia, mostrando o array de notas de um aluno que fez apenas três avaliações, com notas 8.0, 0.0 e 6.5, para uma disciplina que admite no máximo 6 notas: 0 1 2 3 4 5 8.0 0.0 6.5 0.0 0.0 0.0 Neste caso, o tamanho físico (length) vale 6, mas só metade do array está ocupada com dados úteis, isto é, o seu tamanho lógico está valendo 3. As posições restantes não representam notas do aluno, mas apenas o valor padrão que Java utiliza para os tipos primitivos numéricos. Essa área inútil, que popularmente chamamos lixo, não pode ser visitada pelos laços dos métodos que percorrem as notas para cálculos e outros tipos de processamento. Por isso usamos o tamanho lógico como baliza para os laços e não o length. É possível controlar o comportamento acima exposto sem usar um contador como tamanho lógico, mas isso requer outros artifícios que dependem de cada situação. Uma delas é inicializar todo o array com um valor inválido como dado do problema (por exemplo, -1 no caso das notas) de modo a identificar uma posição como lixo. Neste caso, o laço pode percorrer todo o array mas, a cada repetição, um if deve testar a validade do conteúdo. Em Java, o uso do array para simular uma coleção de tamanho variável aplica-se mais quando o tipo é primitivo. Se a coleção é de objetos temos uma classe pronta que sabe fazer isso, a classe ArrayList, que será tratada em Programação II ou Laboratório II. Programação I - Prof. Aníbal - Lista de Exercícios 8 9