// Importa a classe Scanner, que será usada para leitura de dadosimportjava.util.Scanner;publicclassSum{publicstaticvoidmain(String[] args){// Cria um objecto Scanner para ler da entrada padrão ("standard input")
Scanner stdin =new Scanner(System.in);// Chama o método nextInt() para ir buscar o próximo inteiroint a = stdin.nextInt();int b = stdin.nextInt();// Imprime a soma dos dois números
System.out.println(a+b);}}
O meu primeiro programa com Scanner. Copie este
pedaço de código para um ficheiro, compile-o e execute o
programa. A execução deverá ficar "parada" à espera que introduza
dois números. Escreva 2 3, carregue
no enter e verifique que o programa escreve 5 como
resultado.
Importação de classes. Experimente comentar a
segunda linha do programa (a
instrução import) e compile de novo o
código. O que acontece? A classe Scanner faz parte do
pacote java.util,
que contém toda uma série de classes muito úteis que iremos aos
poucos começar a usar.
Espaçamento. Experimente executar o programa
novamente, mas desta vez escrever 2,
carregar no enter, depois
escrever 3 e carregar novamente
no enter, verificando que o programa continue a
funcionar. Isto acontece porque o
método nexInt() aceita qualquer tipo
de espaçamento entre inteiros (sejam apenas um ou vários espaços,
tabs e mudanças de linha).
Erro no tipo de dados. (Input Mismatch)
Execute novamente o programa mas desta vez dê como
input 2.5 3.6. O que acontece?
Porquê?
Lendo outro tipo de dados. Modifique o programa para
que passe a conseguir ler número com casas decimais ao invés de
inteiros. Queremos usar doubles em vez de ints. Que
método deverá ser chamado no lugar
do nextInt()? (espreite novamente
a documentação
da classe Scanner. Teste o seu programa para garantir que
com 2.5 3.6 como entrada o resultado
é 6.1. (Nota: se usar um computador configurado
para português, pode acontecer que ao tentar ler um número decimal
com um ponto receba um "Input Mismatch"; nesse caso é esperado que
use uma vírgula no lugar do ponto; não há problema pois quando
submeter o seu programa ele irá aceitar na mesma pontos - em todo
o caso, se desejar usar pontos também no seu computador
pode modificar
o Locale de todo o programa ou apenas
no Scanner)
Exercício 2) Leitura de strings
importjava.util.Scanner;publicclassCount{publicstaticvoidmain(String[] args){
Scanner stdin =new Scanner(System.in);// Ciclo para iterar sobre todas as linhas do inputint counter =0;while(stdin.hasNextLine()){
counter++;
String s = stdin.nextLine();
System.out.println(counter +": "+ s);}}}
Executar o programa com o input num ficheiro
Faça download do ficheiro hamlet.txt contendo alguns versos de Hamlet, uma peça de William Shakespeare. Compile o código de cima e execute-o fornecendo como input o ficheiro hamlet.txt usando redirecionamento de input na shell:
$ java Count < hamlet.txt
1: To be or not to be that is the question
2: Whether tis nobler in the mind to suffer
3: The slings and arrows of outrageous fortune
4: Or to take arms against a sea of troubles
Note que redirecionar o input (a parte "< hamlet.txt"
na instrução acima) é "equivalente" a introduzir manualmente o
conteúdo do ficheiro via teclado. Esta técnica poderá ser útil para
facilitar o teste de inputs muito grandes ou de vários casos de input.
Lendo tokens Altere o programa, substituindo a
chamada a hasNextLine()
por hasNext(), e a chamada
a nextLine()
por next(). Recompile e execute
novamente o código com o mesmo input. O que acontece agora? O que
está a ser contado? Em Java não existe nenhum "nextString" e
o método next deve ser usado para ler
pedaços de input (tokens) separados por algum tipo de
espaçamento (sejam espaços ou mudanças de linha)
Exercício 3) Utilização de arrays
importjava.util.Scanner;publicclassReadNumbers{// Escrever os numeros guardados num array no stdoutstaticvoidwriteArray(int v[]){for(int i=0; i<v.length; i++)
System.out.println("v["+ i +"] = "+ v[i]);}publicstaticvoidmain(String[] args){
Scanner stdin =new Scanner(System.in);int v[]=newint[10];// Cria um novo array com espaço para 10 inteiros int n = stdin.nextInt();// Ler a quantidade de numeros que se seguemfor(int i=0; i<n; i++)// Ler os numeros a partir do stdin
v[i]= stdin.nextInt();
writeArray(v);// Chamar procedimento que escreve}}
Executar o código. Compile e execute este código,
redirecionando o input a partir do ficheiro numbers.txt $ java ReadNumbers < numbers.txt
Posições do array por preencher. Substitua o 10 no
início do input por um 5 e execute novamente o programa. O que
acontece? Porquê? Note como o
atributo length de um array indica o
tamanho que foi alocado, e não o número de posições
"preenchidas". Note também qual o valor por omissão de um inteiro.
Saindo fora dos limites do
array.(ArrayIndexOutOfBoundsException) Mude o
ficheiro de input para passar a conter 11 números (mude a primeira
linha para 11 e acrescente um número no final da segunda linha) e
execute novamente o programa. O que acontece? Porquê? Note que ao
contrário do C, o Java indica explicitamente quando saimos fora dos
limites de um array. Modifique o programa para passar a aceitar
uma qualquer quantidade de números inteiros (a que for indicada na
primeira linha de input) e teste a sua alteração.
Calculando a amplitude. Acrescente uma função que
recebe um array e devolve um inteiro indicando a amplitude (diferença
entre máximo e mínimo) dos valores guardados no array. Teste o seu
funcionamento e certifique-se que funciona independentemente da
magnitude dos números (podem ser tão pequenos - incluindo números
negativos - ou grandes como quiserem, assumindo que cabem
num int).
Exercício 4) Resolução do Problemas - [ED183] Estatísticas
Este problema é uma continuação do exercício anterior
(falta acrescentar uma nova função para calcular a média)
Para imprimir um double com duas casas
decimais pode usar a instrução printf (como no
C). Por exemplo, imprimir uma variável x com duas
casas decimais
seria System.out.printf("%.2f\n",
x);
Note que não tem de verificar se o input obedece aos
limites dados no enunciado. Pelo contrário, essas
restrições estão lá para lhe garantir que os dados
respeitam esses limites (ex: assim sabe que nunca irão
existir mais que 1000 números inteiros nos inputs que são
dados ao seu programa no Mooshak).
Todas as linhas do input e do output devem terminar com
o caracter de mudança de linha (mesmo a última)
Exercício 5) Resolução dos Problemas - [ED120] Desenhando um
Losango e [ED121] Palíndromos
Para a leitura do input pode usar o que aprendeu exercício
2 desta aula;
Se quiser aceder ao i-ésimo caracter de
uma String
pode usar o método char charAt(int
i), como viu na aula anterior.
Primeiro converta a a linha lida numa string só com letras
minúsculas (sem espaços e pontuações). Faça para isso uma
função que receba uma string e devolva a mesma string com os
espaços retirados e todas as maiúsculas convertidas em
minúsculas. Para isso é útil conhecer a
classe Character,
que contém várias funções para lidar com caracteres. Em
particular:
A função boolean
Character.isLetter(char c) indica se o
caracter c é uma letra;
A função char
Character.toLowerCase(char c) converte o caracter
para a sua versão minúscula
Faça agora uma outra função que recebe uma string e
devolve um valor booleano indicando se a string é ou não um
palíndromo, sendo que pode aplicar esta função à linha já sem
espaços e maiúsculas.
Resolução de Exercícios Adicionais
Estes exercícios são um pouco mais avançados, mas permitem que
exercite conhecimentos de leitura/escrita, uso de instruções
condicionais e uso de instruções de ciclo. As dicas estão acessíveis
se carregar no botão, mas estão "escondidas" para o caso de preferir
primeiro tentar fazer sem spoilers.
Resolva o problema [ED243]
Pizza e também poderá testar a sua solução no Mooshak
Guarde os ingredientes que o Mario não gosta num
array a[] de
tamanho N
Inicialize um contador a zero
Faça um ciclo com P iterações e em cada uma
delas:
Leia os ingredientes da pizza i para um
array de b[] de
tamanho Ki
Crie uma função que
receba a[]
e b[] e verifique a pizza
está ok, ou seja, se não há ingredientes em comum
(basta fazer um dois ciclos no tamanho dos arrays e
comparar elemento a elemento e ver se algum par é
igual)
Chame a função para cada pizza e se estiver ok,
incremente um contador
Imprima o conteúdo do contador.
Resolva o problema [ED244]
Primos e também poderá testar a sua solução no Mooshak.
Este exercício vem na sequência da aula anterior, onde
implementou uma forma um pouco naive de verificar
se um dado número é primo. Executar esse procedimento
neste problema para todos os números no intervalo vai
excecer o limite de tempo (pode experimentar para
verificar o que acontece).
Aqui é suposto que pesquise um pouco seguindo a
sugestão do enunciado: veja por exemplo a entrada da
Wikipedia sobre o Crivo
de Eratóstenes (existem muitos recursos possíveis
online)
A ideia é precisamente implementar o crivo, criando um
array de booleanos prime[i]
(de tamanho 10 milhões) que tenha uma posição i
a true se o número i for primo,
e false caso contrário.