Imprimir quadrado usando apenas while e if [Resolvido]
28 respostas
PhoenixWings
Bom dia. Estou com um problema para fechar o lado vertical direito de um quadrado que é impresso com asteriscos. O usuário insere o valor do lado do quadrado e este deve ser impresso com nº de asteriscos igual ao valor do lado propriamente dito. Obrigado pela ajuda.
packageasteriscoquadrado;/** * * @author Eduardo Felipe */importjava.util.Scanner;publicclassAsteriscoQuadrado{publicstaticvoidmain(String[]args){intl=0,l2,l3,l4;// variáveis utilizadas na construção do quadrado.Scannerinput=newScanner(System.in);// enquanto o usuário não inserir um valor no intervalo de 1 e 20while(l<1||l>20){System.out.print("Informe o lado do quadrado (comprimento de 1 a 20): ");l=input.nextInt();}l2=l;l3=l;l4=l;while(l!=0){//impressão da reta horizontal superiorSystem.out.print("*\b");--l;}// quais são as instruções necessárias para imprimir a reta vertical direita?while(l3!=1){// impressão da reta vertical esquerdaSystem.out.print("\n*");--l3;}while(l4!=1){// impressão da reta horizontal inferiorSystem.out.print("\b*");--l4;}System.out.println();}// fim de main}// fim da classe AsteriscoQuadrado
Tio, não dá para fazer as coisas desse jeito aí que você quer fazer.
Não existe um caracter especial que se chame “retornar uma linha para cima” e que faça o contrário do “\n” que você usou aí.
O jeito certo de fazer isso é com espaços mesmo - mais ou menos assim:
**************
Note que para os lados do quadrado com lado 5, você precisa imprimir um asterisco, a seguir 5 - 2 espaços, então outro asterisco. Você precisa imprimir 5 -2 linhas assim desse jeito. OK?
PhoenixWings
Entendi o que você quis dizer. Mas desta forma que você implementou, eu não teria que escrever a quantidade de asteriscos por conta própria? assim, não adiantaria nada o usuário inserir o lado para que o quadrado fosse desenhado na execução. Não teria como adicionar certas instruções logo abaixo do while do l1 para que fosse impressa a linha vertical direita com o valor do lado que o usuário inseriu ?
E
entanglement
Eu dei o valor “5” só para você entender melhor o meu exemplo. Substitua “5” por “n” onde “n” é o número que foi digitado pelo usuário.
PhoenixWings
Mas eu não estou entendendo uma coisa. Por exemplo, vamos supor que o usuário tenha inserido 10 como valor de lado. Pelo que eu entendi que você me explicou, eu teria que dar espaços até conseguir " encaixar " o lado vertical direito no lado horizontal superior, não é mesmo? ou seja, eu teria que praticamente adivinhar o número que o usuário teria inserido para inserir a quantidade correta de espaços. Se ele inserisse 20, a quantidade de espaços arbitrários que eu teria criado seria insuficiente para esse valor e a reta vertical direita apareceria na metade da projeção da reta horizontal superior. Tipo assim:
******************************
*
*
*
*
E
entanglement
Não, não, não, não tem de adivinhar nada. Você ficou com essa idéia de desenhar cada lado de uma vez, mas isso não é possível usando print, já que não existe um caracter que “suba” em vez de “descer” linhas.
Não é para desenhar um quadrado de lado 5 (por exemplo)? Então o usuário entra com o valor 5, e aí seu programa:
Imprime a primeira linha, que contém 5 (ou seja, N) asteriscos. Use println para terminar a linha (não use “\n” que não é confiável).
Imprime 3 linhas (ou seja, N - 2 linhas), que contém um asterisco, mais N - 2 espaços, e depois um asterisco. Para terminar essa linha, use println.
Imprime a última linha, que contém N asteriscos.
PhoenixWings
entanglement:
mais N - 2 espaços
Como eu faço isso? :?
E
entanglement
Você sabe usar um “for”? O “for” é exatamente a mesma coisa que um “while” disfarçado. Você sabe usar um for para imprimir n - 2 espaços?
for(inti=0; i < n - 2; i++) {System.out.print(" ");
}
Você sabe usar um “for”? O “for” é exatamente a mesma coisa que um “while” disfarçado. Você sabe usar um for para imprimir n - 2 espaços?
Desculpa entanglement, eu deveria ter avisado que o exercício impôs a condição de serem usados só o while e o if. Eu estou tentando dar um jeito de imprimir os asteriscos \b asteriscos decrementando uma variável que eu criei para isso. Depois eu digo se consegui desenvolver o algoritmo. Muito obrigado pela ajuda entanglement!
E
entanglement
Uai, usei um while em vez de for para imprimir n - 2 brancos.
Uma coisa que ajuda bastante em computação é o seguinte: digamos que você saiba resolver as coisas de uma determinada maneira (com “for”), mas essa maneira é proibida.
Mas você sabe que essa tal maneira proibida é equivalente a outra maneira permitida (com “while”), de forma mecânica (você conseguiu ligar os pontos e ver como é que o for é equivalente ao while?)
Então você usa a forma permitida, mas pensando como se fosse a forma proibida.
E
entanglement
Por favor, amigo, não insista nesse jeito de fazer com “\b”. É perda de tempo.
M
marcobiscaro2112
Procure por System.out.printf (ou String.format) e os argumentos possíveis para formatação. Por exemplo:
System.out.printf("%10s%n","Olá");
Esse código imprime “Olá” alinhado à direita, usando 10 casas (ou seja, ele já completa com os devidos espaços se preciso).
M
marcobiscaro2112
Essa eu não sabia… qual o motivo de não ser confiável?
T
thingol
Bom, estava simplificando um pouco o problema pro PhoenixWings.
É que normalmente o caracter que serve para ir para a próxima linha é o “\n”, mas no caso do Windows a sequência correta é “\r\n” (2 caracteres), e o println já toma conta dessa diferença para você.
Em vez de aprender que é para usar “\n” (e descobrir que quando for criar um arquivo no Windows para o Notepad - Bloco de Notas - ler é necessário usar “\r\n” para evitar que o Notepad se confunda), é melhor aprender que se deve usar “println” que já faz as coisas automáticas para você.
M
marcobiscaro2112
É verdade, o Windows tem dessas também… mas no caso do printf, basta usar “%n” que funciona perfeitamente.
PhoenixWings
Obrigado a todos pela ajuda :) . Eu consegui implementar o algoritmo para imprimir as retas verticais da direita e esquerda ao mesmo tempo. Só que agora eu não estou conseguindo colocar o resto dos asteriscos entre a primeira linha e a última linha. Toda instrução que eu escrevo faz com que os asteriscos saiam do escopo do desenho do quadrado. Eu já tentei vários testes mas não consegui. Segue abaixo o código do algoritmo das retas verticais:
// L é o valor do lado que declarei anteriormenteL2=L;L3=L;L4=L;inti=0;/*códigoparaimprimirasretasverticaisdaesquerdaedadireita*aomesmotempo*/while(L!=0){System.out.print("*");while(i<L2){System.out.print(" ");i++;}System.out.print("*");System.out.println();--L;i=0;// atribui novamente ao i o valor zero para que os espaços sejam considerados de novo}
joselmocs
olá phoenix,
não sei se é bem o que você queria, mais fiz uma coisinha aqui... testa pra ver se funciona... acabou meu expediente e estou meio atrasado...
importjava.util.Scanner;publicclassAsteriscoQuadrado{privateintcomprimento=0;privateintgetComprimento(){Scannerinput=newScanner(System.in);returninput.nextInt();}privatevoidgeraLinha(){inti=0;while(i<this.comprimento){System.out.print("*");i++;}}privatevoidexibe(){System.out.print("Informe o lado do quadrado (comprimento de 1 a 20): ");this.comprimento=this.getComprimento();if(this.comprimento<1||this.comprimento>20){this.exibe();}this.geraLinha();System.out.print("\n*");inti=0;while(i<(this.comprimento-2)){System.out.print(" ");i++;}System.out.print("*\n");this.geraLinha();}publicstaticvoidmain(String[]args){newAsteriscoQuadrado().exibe();}}
até mais...
PhoenixWings
Boa noite joselmocs. É parecido com o que eu queria: só faltaram mesmo as linhas verticais terem a quantidade de asteriscos das horizontais. Mas muito obrigado! vou estudar detalhadamente o seu algoritmo agora mesmo!
A idéia consiste em criar o quadrado abaixo (lógico, com o tamanho variando dependendo do valor do lado inserido pelo usuário):
************
Pessoal não consegui, obrigado a todos. Acredito que falta-me conhecimento. Depois eu volto a este código.
joselmocs
Olá phoenix,
entendi o que você quer agora, vê se este código te serve:
importjava.util.Scanner;publicclassAsteriscoQuadrado{privateintcomprimento=0;privateintgetComprimento(){Scannerinput=newScanner(System.in);returninput.nextInt();}privatevoidgeraLinha(){inti=0;while(i<this.comprimento){System.out.print("*");i++;}}privatevoidexibe(){System.out.print("Informe o lado do quadrado (comprimento de 1 a 20): ");this.comprimento=this.getComprimento();if(this.comprimento<1||this.comprimento>20){this.exibe();}this.geraLinha();this.geraHorizontal();this.geraLinha();}privatevoidgeraHorizontal(){intl=0;System.out.print("\n");while(l<(this.comprimento-2)){System.out.print("*");inti=0;while(i<(this.comprimento-2)){System.out.print(" ");i++;}System.out.print("*\n");l++;}}publicstaticvoidmain(String[]args){newAsteriscoQuadrado().exibe();}}
abraços
PhoenixWings
Serve sim, obrigado joselmocs! eu vou estudar o algoritmo implementado por você. Abraços!
Compreendi a lógica do seu algoritmo. Anteriormente, eu havia entendido que comprimento - 2 significava a quantidade de espaços menos os asteriscos. Contudo, eu tinha esquecido que após a impressão do asterisco, o cursor ficava no próprio asterisco.
M
Mart
Olha eu consegui aqui
importjava.util.Scanner;publicclassTestes{publicstaticvoidmain(String[]args){intl=0,l2,l3,l4;// variáveis utilizadas na construção do quadrado.Scannerinput=newScanner(System.in);// enquanto o usuário não inserir um valor no intervalo de 1 e 20while(l<1||l>20){System.out.print("Informe o lado do quadrado (comprimento de 1 a 20): ");l=input.nextInt();}l2=l;l3=l;l4=l;while(l2!=0){// impressão da reta horizontal superiorSystem.out.print("*");--l2;}// quais são as instruções necessárias para imprimir a reta vertical// direita?while(l3!=1){// impressão da reta vertical esquerdaSystem.out.print("\n*");if(l3!=2){for(inti=0;i<l-2;i++){System.out.print("x");}System.out.print("*");}--l3;}while(l4!=1){// impressão da reta horizontal inferiorSystem.out.print("*");--l4;}System.out.println();}// fim de main}// fim da classe AsteriscoQuadrado
aqui funcionou, nao sei se todos os testes de cima funcionam .-.
comecei a aprender java faz 2 semanas, mas esse funcionou^^ espero q ajude
PhoenixWings
marcobiscaro2112:
Procure por System.out.printf (ou String.format) e os argumentos possíveis para formatação. Por exemplo:
System.out.printf("%10s%n","Olá");
Esse código imprime “Olá” alinhado à direita, usando 10 casas (ou seja, ele já completa com os devidos espaços se preciso).
Boa tarde. Aproveitando a dica do marcobiscaro2112, gostaria de saber se seria possível escrever a seguinte instrução: System.out.printf("%xs%n", “Olá”); na qual x seria uma variável que teria recebido anteriormente um valor inteiro qualquer. Se tiver como fazer algo desse tipo, como seria a sintaxe correta para tal instrução?
Obs.: eu dei uma olhada na classe PrintStream e vi que o parâmetro passado para esse System.out.printf é String. Só com a sobreposição (override) que seria possível passar um integer ao invés de uma String?
int espacos = 10;
System.out.printf("%"+ espacos +"s%n", "Olá");
Que ótimo joselmocs, bem prático mesmo! quanto ao %n, ele formata o quê? eu estou estudando pelo livro dos Deitel e no cap. 5 ele ensinou a escrever a seguinte instrução:
Só que não foi explicado nada ainda sobre o %n. Abraços e obrigado!
joselmocs
Ele funciona como o \n (quebra de linha)
PhoenixWings
Consegui desenvolver o " quadrado " ( retângulo ) proposto. O problema de desenvolver um quadrado é que o aumento da quantidade de espaços não é uniforme. Já que a quantidade de espaços para um quadrado de quatro asteriscos é de 5:
**************
Que é diferente da quantidade de espaços do de 5 asteriscos ( que é de 7) e, apesar da diferença entre a quantidade de espaços de um quadrado e outro ser uma P.A de razão 2 , não sei como inseri-la no código.
**********************
Segue abaixo o código:
packageasteriscoquadrado;/** * * @author Eduardo Felipe */publicclassAsteriscoQuadrado{privateintL;inti=0;publicvoidsetL(intL){this.L=L;}publicvoidgeraLinha(){i=0;while(i<L){System.out.print("*");++i;}System.out.println();}publicvoidgeraHorizontal(){i=0;intespaco=L-2;while(i<L-2){System.out.printf("%s%"+espaco+"s%s","*"," ","*");System.out.println();++i;}}}
packageasteriscoquadrado;/** * * @author Eduardo Felipe */importjava.util.Scanner;publicclassAsteriscoQuadradoTest{publicstaticvoidmain(String[]args){intL=0;AsteriscoQuadradoq=newAsteriscoQuadrado();Scannerinput=newScanner(System.in);while(L<1||L>20){System.out.print("Informe o tamanho do lado do quadrado (entre 1 e 20): ");L=input.nextInt();}q.setL(L);q.geraLinha();q.geraHorizontal();q.geraLinha();}}
M
marcobiscaro2112
Ele funciona como o \n (quebra de linha)
Na verdade o “%n” é uma quebra de linha que funciona independentemente da plataforma (no Windows ele é traduzido como “\r\n” e em outros SOs como “\n”).
joselmocs
Boa noite Phoenix,
Tente alterando estes 2 métodos da classe AsteriscoQuadrado:
public void geraLinha() {
i = 0;
while (i < L) {
if (i == (L -1)) {
System.out.print("*");
}
else {
System.out.print("* ");
}
++i;
}
System.out.println();
}e
public void geraHorizontal() {
i = 0;
while (i < L - 2) {
System.out.printf("*%" + ((L * 2) -2) + "s%n", "*");
++i;
}
}
edit.:
Retirei 2 parâmetros no printf do metodo geraHorizontal pra você ver que pode ser passado qualquer coisa no primeiro parâmetro.
System.out.printf("Meu Nome é %s","Joselmo");
Abraços
PhoenixWings
Obrigado joselmocs! eu vou usar o recurso de comparação de códigos do NetBeans para analisar cuidadosamente a diferença de um algoritmo para o outro. Abraços!