Как напечатать заданный ромбовидный узор в Java?

***********
***** *****
****   ****
***     ***
**       **
*         *
**       **
***     ***
****   ****
***** *****
***********

В основном мне просто нужна идея правильно поставить пробелы. Мой код до сих пор.

public class Pyramid3 {

    public static void main(String[] args) {

        int i, j;
        int noOfCol = 11;

        for (i = 1; i <= 11; i++) {

            for (j = 1; j <= noOfCol; j++) {
                System.out.print("*");
            }

            System.out.println();

            if (i == 1) {
                noOfCol--;
            } else if (i > 1 && i < 6) {
                noOfCol = noOfCol - 2;
            } else if (i > 6) {
                noOfCol = noOfCol + 2;
            }
        }
    }
}

person Yash Jain    schedule 22.02.2015    source источник


Ответы (6)


Чтобы решить вопросы об ASCII-графике, можно попытаться найти шаблоны в разных строках. Видно, что каждая строка содержит некоторое количество звездочек (*), количество пробелов (возможно, ноль) и количество звездочек.

Итак, мы сначала напишем вспомогательную функцию:

public static String generateRow (int n1, int n2, int n3) {
    StringBuilder sb = new StringBuilder();
    for(int i = 0; i < n1; i++) {
        sb.append('*');
    }
    for(int i = 0; i < n2; i++) {
        sb.append(' ');
    }
    for(int i = 0; i < n3; i++) {
        sb.append('*');
    }
}

Теперь нам нужно только определить количество звездочек и пробелов. Первая и последняя строки содержат только n звездочек, поэтому мы можем написать:

System.out.println(generateRow(n,0,0));

Вторая строка содержит один пробел посередине, если n нечетное, и два, если n четное, так что это выглядит так:

int ns = 2-(n%2);
int na = (n-ns)/2;
System.out.println(generateRow(na,ns,na));

Поскольку na – это размер минус количество пробелов, деленное на 2.

Теперь в каждой строке количество пробелов увеличивается на два, поэтому количество звездочек уменьшается на единицу. Цикл останавливается, если остается только одна звездочка. Таким образом, вы можете переписать это как:

int ns = 2-(n%2);
int na = (n-ns)/2;
for(; na >= 1; na--, ns += 2) {
    System.out.println(generateRow(na,ns,na));
}

Теперь нижняя часть просто производится обратным процессом. Сначала нам нужно отменить последнее уменьшение приращения na и ns:

na += 2;
ns -= 4;

И затем мы зацикливаемся, пока количество пробелов не станет меньше одного:

for(; ns > 1; na++, ns -= 2) {
    System.out.println(generateRow(na,ns,na));
}

сложив все это вместе, это приводит к:

public static void generateDiamond (int n) {
    System.out.println(generateRow(n,0,0));
    int ns = 2-(n%2);
    int na = (n-ns)/2;
    for(; na >= 1; na--, ns += 2) {
        System.out.println(generateRow(na,ns,na));
    }
    na += 2;
    ns -= 4;
    for(; ns >= 1; na++, ns -= 2) {
        System.out.println(generateRow(na,ns,na));
    }
    System.out.println(generateRow(n,0,0));
}

демонстрация jdoodle.

Для размеров 2, 3, 5, 8, 11 и 33 создается:

**
**

***
* *
***

*****
** **
*   *
** **
*****

********
***  ***
**    **
*      *
**    **
***  ***
********

***********
***** *****
****   ****
***     ***
**       **
*         *
**       **
***     ***
****   ****
***** *****
***********

*********************************
**************** ****************
***************   ***************
**************     **************
*************       *************
************         ************
***********           ***********
**********             **********
*********               *********
********                 ********
*******                   *******
******                     ******
*****                       *****
****                         ****
***                           ***
**                             **
*                               *
**                             **
***                           ***
****                         ****
*****                       *****
******                     ******
*******                   *******
********                 ********
*********               *********
**********             **********
***********           ***********
************         ************
*************       *************
**************     **************
***************   ***************
**************** ****************
*********************************
person Willem Van Onsem    schedule 22.02.2015

Это код, извините за плохую документацию, надеюсь, это поможет.

PS: чтобы решить любую подобную проблему, просто используйте белую бумагу и карандаш, затем создайте сетки столбцов и индекс «i», затем нарисуйте отношение, затем вы можете использовать его как условие цикла.

public class Test {
    public static void main(String[] args) {
        int n = 10;

        // Top
        for (int i = n; i > 0; i--) {
            // Stars
            for (int j = 0; j < i; j++) {
                System.out.print("*");
            }
            // Spaces
            for (int j = i; j < n; j++) {
                System.out.print(" ");
            }
            // Stars
            for (int j = i; j < n; j++) {
                System.out.print(" ");
            }
            // Stars
            for (int j = 0; j < i; j++) {
                System.out.print("*");
            }
            System.out.println();
        }

        // Bottom
        for (int i = 2; i < n + 1/* Note the shift here */; i++) {
            // Stars
            for (int j = 0; j < i; j++) {
                System.out.print("*");
            }
            // Spaces
            for (int j = i; j < n; j++) {
                System.out.print(" ");
            }
            // Spaces
            for (int j = i; j < n; j++) {
                System.out.print(" ");
            }
            for (int j = 0; j < i; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

Надеюсь, поможет :)

person AbdElraouf Sabri    schedule 22.02.2015

Я предпочитаю короткие и лаконичные ответы. Мой использует горизонтальную и вертикальную оси симметрии алмаза: идея состоит в том, чтобы вычислить 1/4 часть алмаза, а затем отразить ее сначала вокруг вертикальной, а затем вокруг горизонтальной оси (_ — это пробел).

******
*****_
****__  
***___
**____
*_____

Во-первых, короткая служебная функция для повторения символа n раз :

String repeat(String s, int times) {
  return times == 0 ? "" : new String(new char[times]).replace("\0", s);
}

Вот код (с использованием лямбда-выражений Java 8 для печати результата и этот ответ для обращения строки)

 // height and width of the diamond
int size = 11;
// Mhh diamonds
List<String> l = new ArrayList<>();
// len includes the axis, too
for (int i=0, len = size/2 + 1;i<len;i++) {
  String s = repeat("*", len - i) + repeat(" ", i);
  //Mirror, omitting the axis itself and append
  s += (new StringBuilder(s)).reverse().substring(1);
  l.add(s);
}
// Print the upper part
l.forEach(System.out::println);
// mirror around the horizontal axis
Collections.reverse(l);
// Omit the horizontan axis and print the rest
l.subList(1,l.size()).forEach(System.out::println);

Это 8-9 строк кода для ромба произвольного размера плюс 3 для метода повторения.

Результат:

***********
***** *****
****   ****
***     ***
**       **
*         *
**       **
***     ***
****   ****
***** *****
***********
person user3001    schedule 22.02.2015

Вы можете напечатать пустой ромб, вписанный в квадрат, используя два вложенных потока по строкам и столбцам от -n до n. Форма ромба получается, когда n > iAbs + jAbs:

int n = 5;
String[] arr = IntStream
        .rangeClosed(-n, n)
        .map(Math::abs)
        .mapToObj(i -> IntStream
                .rangeClosed(-n, n)
                .map(Math::abs)
                // an empty rhombus inscribed in a square
                .mapToObj(j -> i + j < n ? " " : "*")
                .collect(Collectors.joining(" ")))
        .toArray(String[]::new);
Arrays.stream(arr).forEach(System.out::println);

Выход:

* * * * * * * * * * *
* * * * *   * * * * *
* * * *       * * * *
* * *           * * *
* *               * *
*                   *
* *               * *
* * *           * * *
* * * *       * * * *
* * * * *   * * * * *
* * * * * * * * * * *

См. также:
Рисование числового ромба
Пустой ромб с цифрами

person Community    schedule 17.02.2021

Вот мое решение точного ромбовидного узора, который вы хотели.

У меня есть метод, который облегчает мне печать.

private static void put(char c, int n, boolean NL) {
    for (int a = 0; a < n; a++) System.out.print(c);
    if (NL) System.out.println();
}

По сути, вы говорите ему: какой символ печатать, сколько раз и следует ли добавлять новую строку после завершения печати.

Затем приходит фактическое решение:

put('*', 11, true);
int count = 0;
for (int a = 5; a >= 1; a--) {
    put('*', (int) Math.ceil(a), false);
    put(' ', count++ * 2 + 1, false);
    put('*', (int) Math.ceil(a), true);
}
count = 4;
for (int a = 2; a < 6; a++) {
    put('*', (int) Math.ceil(a), false);
    put(' ', count-- * 2 - 1, false);
    put('*', (int) Math.ceil(a), true);
}
put('*', 11, true);

Честно говоря, было немного грубой логики, но в целом идея проста. Я отслеживаю расстояние с помощью переменной счетчика и печатаю верх и низ ромба отдельно.

Извините за отсутствие документации, так как у меня не было много времени, чтобы решить эту проблему. Надеюсь, поможет!

А за отсутствием тестирования вот вывод.

***********
***** *****
****   ****
***     ***
**       **
*         *
**       **
***     ***
****   ****
***** *****
***********
person Boris    schedule 22.02.2015

public static void main(String[] args) {
    int n = 7;
    for (int i = -n; i <= n; i++) {
        for (int j = -n; j <= n; j++)
            if (Math.abs(i) + Math.abs(j) >= n
                    // in chessboard order
                    && (i + j) % 2 != 0
                    // vertical borders
                    || Math.abs(j) == n)
                System.out.print("*");
            else
                System.out.print(" ");
        System.out.println();
    }
}

Выход:

** * * * * * **
* * * * * * * *
** * *   * * **
* * *     * * *
** *       * **
* *         * *
**           **
*             *
**           **
* *         * *
** *       * **
* * *     * * *
** * *   * * **
* * * * * * * *
** * * * * * **

См. также: Пустой ромб с цифрами

person Community    schedule 23.06.2021