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. :slight_smile:

package asteriscoquadrado;

/**
 *
 * @author Eduardo Felipe
 */
import java.util.Scanner;

public class AsteriscoQuadrado
{

    public static void main(String[] args)
    {

        int l = 0, l2, l3, l4;
        // variáveis utilizadas na construção do quadrado.
        Scanner input = new Scanner(System.in);

        // enquanto o usuário não inserir um valor no intervalo de 1 e 20
        while (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 superior
            System.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 esquerda
            System.out.print("\n*");
            --l3;
        }

        while (l4 != 1)
        {
            // impressão da reta horizontal inferior
            System.out.print("\b*");
            --l4;
        }

        System.out.println();
    } // fim de main
} // fim da classe AsteriscoQuadrado

28 Respostas

E

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

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

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

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 (int i = 0; i < n - 2; i++) {
    System.out.print (" ");
}

Pois bem, o “while” correspondente seria:

int i;
i = 0;
while (i < n - 2) {
    System.out.print (" ");
    i++;
}
PhoenixWings

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! :slight_smile:

E

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

Por favor, amigo, não insista nesse jeito de fazer com “\b”. É perda de tempo.

M

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

Essa eu não sabia… qual o motivo de não ser confiável?

T

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

É 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 anteriormente
L2 = L;
L3 = L;
L4 = L;
int i = 0;

/* código para imprimir as retas verticais da esquerda e da direita
         * ao mesmo tempo */
        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...

import java.util.Scanner;

public class AsteriscoQuadrado {

    private int comprimento = 0;

    private int getComprimento() {
        Scanner input = new Scanner(System.in);
        return input.nextInt();
    }

    private void geraLinha() {
        int i = 0;
        while (i < this.comprimento) {
            System.out.print("*");
            i++;
        }
    }

    private void exibe() {
        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*");
        int i = 0;
        while (i < (this.comprimento -2)) {
            System.out.print(" ");
            i++;
        }
        System.out.print("*\n");

        this.geraLinha();
    }

    public static void main(String[] args) {
        new AsteriscoQuadrado().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. :cry:

joselmocs

Olá phoenix,

entendi o que você quer agora, vê se este código te serve:

import java.util.Scanner;

public class AsteriscoQuadrado {

    private int comprimento = 0;

    private int getComprimento() {
        Scanner input = new Scanner(System.in);
        return input.nextInt();
    }

    private void geraLinha() {
        int i = 0;
        while (i < this.comprimento) {
            System.out.print("*");
            i++;
        }
    }

    private void exibe() {
        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();
    }

    private void geraHorizontal() {
        int l = 0;
        System.out.print("\n");
        while (l < (this.comprimento -2)) {
            System.out.print("*");
            int i = 0;
            while (i < (this.comprimento -2)) {
                System.out.print(" ");
                i++;
            }
            System.out.print("*\n");
            l++;
        }
    }

    public static void main(String[] args) {
        new AsteriscoQuadrado().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

Olha eu consegui aqui

import java.util.Scanner;

public class Testes {

	public static void main(String[] args) {

		int l = 0, l2, l3, l4;
		// variáveis utilizadas na construção do quadrado.
		Scanner input = new Scanner(System.in);

		// enquanto o usuário não inserir um valor no intervalo de 1 e 20
		while (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 superior
			System.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 esquerda
			System.out.print("\n*");

			if (l3 != 2) {
				for (int i = 0; i < l - 2; i++) {
					System.out.print("x");
				}
				System.out.print("*");
			}

			--l3;

		}

		while (l4 != 1) {
			// impressão da reta horizontal inferior
			System.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?

joselmocs

Boa tarde Phoenix, ambas abaixo funcionam…

String espacos = "10"; System.out.printf("%"+ espacos +"s%n", "Olá");

int espacos = 10; System.out.printf("%"+ espacos +"s%n", "Olá");

Só seria integer se o primeiro argumento do printf fosse somente um número, desta forma:

int espacos = "10"; System.out.printf(espacos, "Olá");

Uma letra qualquer já o torna String

int espacos = "10"; System.out.printf(espacos +"letra", "Olá");

PhoenixWings

joselmocs:
Boa tarde Phoenix, ambas abaixo funcionam…

String espacos = "10"; System.out.printf("%"+ espacos +"s%n", "Olá");

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:

System.out.printf( "%s%20s \n", "Ano", "Quantidade depositada");

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:

package asteriscoquadrado;

/**
 *
 * @author Eduardo Felipe
 */
public class AsteriscoQuadrado
{

    private int L;
    int i = 0;

    public void setL(int L)
    {
        this.L = L;
    }

    public void geraLinha()
    {

        i = 0;
        while (i < L)
        {
            System.out.print("*");
            ++i;
        }
        System.out.println();
    }

    public void geraHorizontal()
    {

        i = 0;
        int espaco = L - 2;
        while (i < L - 2)
        {
            System.out.printf("%s%" + espaco + "s%s", "*", " ", "*");
            System.out.println();
            ++i;
        }

    }
}
package asteriscoquadrado;

/**
 *
 * @author Eduardo Felipe
 */
import java.util.Scanner;
public class AsteriscoQuadradoTest
{

   public static void main(String[] args)
   {

      int L = 0;
      AsteriscoQuadrado q = new AsteriscoQuadrado();
      Scanner input = new Scanner(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

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!

Criado 25 de fevereiro de 2010
Ultima resposta 28 de fev. de 2010
Respostas 28
Participantes 6