Пирамида чисел в Java

Я пытаюсь напечатать пирамиду на Java, которая выглядит примерно так:

                9
              8 9 8
            7 8 9 8 7
          6 7 8 9 8 7 6
        5 6 7 8 9 8 7 6 5
      4 5 6 7 8 9 8 7 6 5 4
    3 4 5 6 7 8 9 8 7 6 5 4 3
  2 3 4 5 6 7 8 9 8 7 6 5 4 3 2
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1

Я искал способы решить эту проблему в Интернете, и я наткнулся на это:

class Pyramid {
    public static void main(String[] args) {
        int x = 7;
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= x - i; j++)
                System.out.print("   ");
            for (int k = i; k >= 1; k--)
                System.out.print((k >= 10) ? +k : "  " + k);
            for (int k = 2; k <= i; k++)
                System.out.print((k >= 10) ? +k : "  " + k);
            System.out.println();
        }
    }
}

Может ли кто-нибудь помочь мне понять это? Вот что я понял: внешний цикл увеличивается до 7, в то же время внутренний цикл j увеличивается до x - i, что равно 6 для первой итерации внешнего цикла, затем 5 ... и так далее. Таким образом, в основном левая сторона пирамиды представляет собой просто перевернутый треугольник из пустых пространств.

У меня возникли проблемы с выяснением того, что происходит в двух других вложенных циклах и странных частях if-else внутри операторов печати.


person Ajit    schedule 04.09.2012    source источник


Ответы (9)


Давайте рассмотрим это шаг за шагом. Как вы уже поняли, x — это переменная, представляющая высоту пирамиды.

то, как вы тоже правильно выяснили, первый цикл создает отступ текущей строки цифр

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

теперь странно выглядящие части if-else, как вы их называете, представляют собой тернарный условный оператор, и единственная цель, которую они выполняют в этом коде, — это исправление интервала между числами, когда пирамида содержит числа> = 10, опуская ведущий пробел числа. :)

person Andreas Grapentin    schedule 04.09.2012

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

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

Так что не начинайте со своей проблемы.

Q1: Как напечатать пирамиду чисел?

Поскольку мы этого не знаем, давайте сосредоточимся на чем-то другом.

Чтобы улучшить наше наблюдение, мы можем добавить некоторые детали фона.

  1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
0 _ _ _ _ _ _ _ _ 9 _ _ _ _ _ _ _ _
1 _ _ _ _ _ _ _ 8 9 8 _ _ _ _ _ _ _
2 _ _ _ _ _ _ 7 8 9 8 7 _ _ _ _ _ _
3 _ _ _ _ _ 6 7 8 9 8 7 6 _ _ _ _ _
4 _ _ _ _ 5 6 7 8 9 8 7 6 5 _ _ _ _
5 _ _ _ 4 5 6 7 8 9 8 7 6 5 4 _ _ _
6 _ _ 3 4 5 6 7 8 9 8 7 6 5 4 3 _ _
7 _ 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 _
8 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1

Теперь время наблюдения.

Из этого наблюдения мы можем прийти к следующим идеям.

Идея: Пирамида – это конструкция из двух треугольников.

Вывод: Легче написать половину этой пирамиды. Итак, давайте перефразируем кислую проблему.

Q2: Как написать порядковый номер, который выглядит как треугольник?

Это действительно просто, нам просто нужно два цикла, первый цикл будет отвечать за столбцы, а другой — за строки.

for (int column = 1; column <= 9; column++) {
    for (int row = 1; row <= 9; row++) {
        // Observe what will happen if
        // we use == or <= or > or <>
        if (column ## row) {
            System.out.print(row);
        } else {
            System.out.print(" ");
        }
    }
    System.out.println(' ');
}

Когда вы выполните свое первое задание, вы сможете печатать квадраты, треугольники, строки чисел на экране.

Итак, когда мы знаем, как напечатать треугольник следующим образом:

   r
c    1 2 3 4 5 6 7 8 9 
   1 _ _ _ _ _ _ _ _ 9 
   2 _ _ _ _ _ _ _ 8 9 
   3 _ _ _ _ _ _ 7 8 9 
   4 _ _ _ _ _ 6 7 8 9 
   5 _ _ _ _ 5 6 7 8 9 
   6 _ _ _ 4 5 6 7 8 9 
   7 _ _ 3 4 5 6 7 8 9 
   8 _ 2 3 4 5 6 7 8 9 
   9 1 2 3 4 5 6 7 8 9 

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

   r
c    0 1 2 3 4 5 6 7 8  
   0 _ _ _ _ _ _ _ _ 9 
   1 _ _ _ _ _ _ _ 8 9 
   2 _ _ _ _ _ _ 7 8 9 
   3 _ _ _ _ _ 6 7 8 9 
   4 _ _ _ _ 5 6 7 8 9 
   5 _ _ _ 4 5 6 7 8 9 
   6 _ _ 3 4 5 6 7 8 9 
   7 _ 2 3 4 5 6 7 8 9 
   8 1 2 3 4 5 6 7 8 9 

Когда вы преуспеете в этом, мы остановимся на мгновение и подумаем.

Почему мы должны повторять все эти операции для каждой строки? Если бы мы могли где-то размещать значения, нам не нужно было бы больше думать и вычислять их, а только сосредоточиться на записи всего результата на экран.

Решением этой проблемы являются массивы и концепция подхода, известного как динамическое программирование. В этом подходе мы пытаемся запомнить где-то вещи, которые будут использоваться для будущих операций.

Таким образом, червяк позволяет просто присвоить число и массив вместо их печати.

[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [9]
[ ] [ ] [ ] [ ] [ ] [ ] [ ] [8] [9]
[ ] [ ] [ ] [ ] [ ] [ ] [7] [8] [9]
[ ] [ ] [ ] [ ] [ ] [6] [7] [8] [9]
[ ] [ ] [ ] [ ] [5] [6] [7] [8] [9]
[ ] [ ] [ ] [4] [5] [6] [7] [8] [9]
[ ] [ ] [3] [4] [5] [6] [7] [8] [9]
[ ] [2] [3] [4] [5] [6] [7] [8] [9]
[1] [2] [3] [4] [5] [6] [7] [8] [9]

В и вы должны были придумать такой код

int[] array = new int[9];

for (int column = array.length; column > 0; column--) {
    for (int row = 0; row <= array.length; row++) {
        if (column == row) {
            array[row - 1] = column;
        }
    }
    System.out.println(Arrays.toString(array));
}

Итак, что ясно из этого кода, так это то, что мы для каждого шага используем set только одно значение. Это представлено ниже

9  [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [9] - Step one we put nine
8  [ ] [ ] [ ] [ ] [ ] [ ] [ ] [8] [ ] - Step two we put eight
7  [ ] [ ] [ ] [ ] [ ] [ ] [7] [ ] [ ]
6  [ ] [ ] [ ] [ ] [ ] [6] [ ] [ ] [ ]
5  [ ] [ ] [ ] [ ] [5] [ ] [ ] [ ] [ ]
4  [ ] [ ] [ ] [4] [ ] [ ] [ ] [ ] [ ]
3  [ ] [ ] [3] [ ] [ ] [ ] [ ] [ ] [ ]
2  [ ] [2] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
1  [1] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]

После девяти шагов мы заполним весь массив числами.

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

И код, который делает волшебство, должен выглядеть так

public static void pyramide(int levels) {
    int[] tab = new int[levels];
    for (int row = tab.length; row > 0; row--) {
        tab[row - 1] = row;
        //Print left
        for (int i = 0; i < tab.length; i++) {
            if (tab[i] != 0) {
                System.out.print(tab[i]);
            } else {
                System.out.print(' ');
            }
        }
        //Print right
        for (int i = tab.length - 2; i >= row - 1; i--) {
            if (tab[i] != 0) {
                System.out.print(tab[i]);
            }
        }
        System.out.println("");
    }
}
person Damian Leszczyński - Vash    schedule 04.09.2012
comment
Спасибо . Это было очень полезно - person Ajit; 09.09.2012

Это домашнее задание. Вы узнаете больше, делая это самостоятельно, а не слепо копируя чужую работу.

Начните с аналогичной, но более простой задачи:

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

Вы можете распечатать этот треугольник? Напишите свой собственный код и проверьте, правильно ли он работает.

Теперь измените свой код, чтобы печатать числа вместо звездочек:

    1
   123
  12345
 1234567

Вы можете распечатать этот треугольник? Напишите свой собственный код и проверьте, правильно ли он работает.

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

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

person rossum    schedule 04.09.2012

вот так

public class Pyramid {
    public static void main(String[] args) {
        int[] arry = new int[10];
        for (int i = 1; i <= 9; i++)
            arry[i] = i;
        int index = 0;
        for (int i = 9; i > 0; i--) {
            int loop = 1, tempLoop = 0;

            for (int k = 0; k < 9; k++) {
                if (k < (9 - index))
                    System.out.print(" ");
                else
                    System.out.print(arry[k] + " ");
            }

            for (int k = 9; k >= i && (tempLoop++) <= index; k--) {
                System.out.print(arry[k] + " ");
            }
            index++;
            System.out.println();
        }
    }
}

Выход:

         9 
        8 9 8 
       7 8 9 8 7 
      6 7 8 9 8 7 6 
     5 6 7 8 9 8 7 6 5 
    4 5 6 7 8 9 8 7 6 5 4 
   3 4 5 6 7 8 9 8 7 6 5 4 3 
  2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 
 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 
person twid    schedule 04.09.2012

Здесь в двух других вложенных циклах:

for (int k = i; k >= 1; k--)
System.out.print((k >= 10) ?+ k : "  " + k);

for (int k = 2; k <=i; k++)
System.out.print((k >= 10) ?+ k : "  " + k);

если условие k>=10 верно, то значение k будет отображаться без пробела. Если оно ложно, то значение k будет отображаться с пробелом.

person Tushar Paliwal    schedule 09.09.2012

Подумайте о двух шаблонах.

Первый шаблон, распечатайте слева и справа.

Второй шаблон, распечатайте каждую строку и проверьте зазор с точкой начала печати.

public class NumberPyramid {
    public static void main(String[] args) {
        int part = 2;
        int stage = 5; // set tree stage.
        if (part == 2) {
            int cnt = 0;
            // thinking two part.
            for (int i = stage; i > 0; i--) {
                for (int j = 1; j <= stage; j++) {
                    if (stage - j <= cnt) {
                        System.out.print(j + " ");
                    } else {
                        System.out.print("  ");
                    }
                }
                for (int k = stage; k > 0; k--) {
                    if (k != stage) {
                        if (stage - cnt <= k) {
                            System.out.print(k + " ");
                        } else {
                            System.out.print("  ");
                        }
                    }
                }
                System.out.println("");
                cnt++;
            }
        } else if (part == 1) {// think whole lines.
            int gap = 0;
            for (int j = 0; j < stage; j++) {
                for (int i = 1; i <= stage * 2; i++) {
                    if (Math.abs(i - stage) <= gap) {
                        System.out.print(stage - gap + " ");
                    } else
                        System.out.print("  ");
                }
                System.out.println("");
                gap++;
            }
        }
    }
}

Выход:

        5         
      4 5 4       
    3 4 5 4 3     
  2 3 4 5 4 3 2   
1 2 3 4 5 4 3 2 1 
person Minkpac    schedule 14.06.2015

Увидел в этом потенциальный вопрос для интервью и хотел попытаться реализовать его с помощью потоковых методов Java 8. Решение ниже:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class App {
    public static void main(String[] args) {
        int min = 1;
        int max = 9;
        List<List<String>> pyramid = new ArrayList<>();
        IntStream.iterate(max, i -> i - 1).limit(max)
            .forEach(s -> {
                List<String> pyramidRow = new ArrayList<>();
                IntStream.rangeClosed(min, max)
                    .forEach(j -> {
                        if (j < s) pyramidRow.add(" ");
                        else pyramidRow.add(String.valueOf(j));
                    });
                IntStream.iterate(max - 1, i -> i - 1).limit(max - 1)
                    .forEach(j -> {
                        if (j < s) pyramidRow.add(" ");
                        else pyramidRow.add(String.valueOf(j));
                    });
                pyramid.add(pyramidRow);
            });
        pyramid.stream()
            .forEach(pyra -> {
                pyra.forEach(System.out::print);
                System.out.println();
            });
    }
}

Выход:

        9        
       898       
      78987      
     6789876     
    567898765    
   45678987654   
  3456789876543  
 234567898765432 
12345678987654321
person douglas    schedule 28.03.2016

Представьте себе координатную плоскость с началом в верхней средней точке:

class CoordinatePlane {
    public static void main(String[] args) {
        int n = 8;
        // vertical axis
        for (int i = 0; i <= n; i++) {
            // horizontal axis
            for (int j = 1 - n; j <= n - 1; j++)
                // print axes, otherwise whitespaces
                System.out.printf("%2s", i == 0 ? j : j == 0 ? i : "");
            // print a new line
            System.out.println();
        }
    }
}

Координатная плоскость:

-7-6-5-4-3-2-1 0 1 2 3 4 5 6 7
               1              
               2              
               3              
               4              
               5              
               6              
               7              
               8              

С небольшими изменениями получается пирамида чисел:

class Pyramid {
    public static void main(String[] args) {
        int n = 8;
        // vertical axis
        for (int i = 1; i <= n; i++) {
            // horizontal axis
            for (int j = 1 - n; j <= n - 1; j++) {
                // absolute value - the distance from the zero point
                int jAbs = Math.abs(j);
                // print numbers, otherwise whitespaces
                System.out.printf("%2s", jAbs < i ? n - jAbs : "");
            }
            // print a new line
            System.out.println();
        }
    }
}

Пирамида чисел:

               8              
             7 8 7            
           6 7 8 7 6          
         5 6 7 8 7 6 5        
       4 5 6 7 8 7 6 5 4      
     3 4 5 6 7 8 7 6 5 4 3    
   2 3 4 5 6 7 8 7 6 5 4 3 2  
 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1

См. также: Как получить следующий отформатированный вывод?

person Community    schedule 13.07.2021

person    schedule
comment
Добро пожаловать в Stack Overflow. Прочтите Как ответить. Обратите внимание, что несколько других ответов на этот почти 9-летний вопрос тратят большую часть своего времени на объяснение. Stack Overflow предназначен для обучения, а не для слепого копирования и вставки фрагментов кода. - person Chris; 17.07.2021