2016-11-29 3 views
-1

Для проекта класса мы должны иметь возможность нарисовать треугольник в двумерном массиве символов. Алгоритмически я не могу понять, как это сделать.Как нарисовать треугольник в 2D-массиве (Java)

Мой текущий код это (но это не работает):

public void fill() { 
     for (int i = 0; i < h; i++) { 
      double x=h; 
      while(x<=0){ 
       drawing.setPoint(i, x, myChar); 
       x=Math.ceil(x/2); 
      } 
     } 
    } 

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

....*.... 
...***... 
..*****.. 
.*******. 
********* 

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

Спасибо за вашу помощь

+1

Какой выходной сигнал вы ожидаете? – bradimus

+0

@bradimus Я обновил его –

+0

Если h <= 0, вы никогда не войдете в цикл while, и если это так, вы тоже не войдете в цикл for. – dogwin

ответ

3

Основываясь на вашем чертеже, необходимо 9 столбцов на 5 строк. Так,

int height = 5; 
int width = 2*height - 1; 

Хотя я не уверен, что drawing.setPoint(i, x, myChar); делает, я думаю, что этот пример поможет вам идти. Я построю String на основе char s.

char fill = '*'; 
char blank = '.'; 

Я начну строки в 0, но столбцы в 1, чтобы сделать математику немного яснее.

Для row = 0, ....*.... вам нужна одна звезда в column = 5.

Для row = 1, ...***... вам нужны три звезды в column = 4,5,6.

Для row = 3, .*******. вам нужны семь звезд в column = 2,3,4,5,6,7,8.

Обратите внимание, что для row i вам нужна звезда в column j, если расстояние между height = 5 и column j меньше или равна i. То есть, когда | height - column | <= row

for (int row = 0; row < height; row ++) { 
    StringBuilder line = new StringBuilder(width); 
    for (int column = 1; column <= width; column ++) { 
     char out = Math.abs(column - height) <= row ? fill : blank; 
     line.append(out); 
    } 
    System.out.println(line); 
} 

Это дает

....*.... 
...***... 
..*****.. 
.*******. 
********* 

Я предполагаю, что вы можете использовать Math.abs, так как ваш пример имеет Math.ceil. Если нет, вы можете конвертировать Math.abs в заявление if.

1

Существует множество способов решить эту проблему, и вы уже видели один ответ, который рисует изображение подряд за строкой.

Я предполагаю, что у вас уже есть подпрограммы для создания char[][] и для печати символов в этом массиве массивов на экран. Похоже, что у вас уже есть метод setPoint(), чтобы вытолкнуть точку в структуру.

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

Многие опытные кодировщики теперь используют Test Driven Design, и вы можете узнать из этого: начать с простого случая, создать тест для этого, сделать этот тест, повторить с большим количеством тестов, пока не будет больше тестов для записи ,

В конце концов вы должны изучить тестовую структуру, такую ​​как jUnit, но пока вы можете «протестировать», просто запустив свою программу. Итак, первый тест: работает ли он на height == 1?

Вы можете пройти этот тест (на данный момент, что средства, запустить программу и увидеть, что выход смотрит вправо) с:

public void drawTriangle(int height) { 
     drawing.setPoint(0,5,'*') 
    } 

работы.

Теперь, чтобы сделать его работу для height==2:

public void drawTriangle(int height) { 
     drawing.setPoint(0,5,'*'); 
     if(height == 2) { 
     drawing.setPoint(1,4,'*'); 
     drawing.setPoint(1,5,'*'); 
     drawing.setPoint(1,6,'*'); 
     } 
    } 

Это все еще работает height == 1, но также работает для height == 2.

Но вы можете сразу увидеть возможность для цикла заменить эти три команды для второй строки. Итак:

public void drawTriangle(int height) { 
     drawing.setPoint(0,5,'*'); 
     if(height == 2) { 
     for(int 4; i<7; i++) { 
      drawing.setPoint(1,i,'*'); 
     } 
     } 
    } 

... и вы можете вытащить, что из в метод:

public void drawTriangle(int height) { 
     drawing.setPoint(0,5,'*'); 
     if(height == 2) { 
      drawRow2(); 
     } 
    } 

    private void drawRow2() { 
     for(int 4; i<7; i++) { 
     drawing.setPoint(1,i,'*'); 
     } 
    } 

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

Надеюсь, вы увидите, где это происходит. Вы можете изменить drawRow2(), чтобы быть более общим - drawRow(int rowNumber), и постепенно заменять буквальные числа там переменными, происходящими от rowNumber. Затем вы можете использовать drawRow(0), чтобы нарисовать первую строку, и drawRow(1), чтобы нарисовать вторую. Затем вы можете нарисовать треугольник трех строк, добавив drawRow(2), а затем вы можете улучшить это, используя вместо этого цикл.