对于一个类项目,我们需要能够在二维字符数组中绘制一个三角形。从算法上讲,我无法弄清楚如何做到这一点。
我当前的代码是这样的(但它不起作用):
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);
}
}
}
我希望输出看起来像这样:
....*....
...***...
..*****..
.*******.
*********
我们不能使用任何与绘图有关的预先存在的方法或类。
感谢您的帮助
答案 0 :(得分:3)
根据您的绘图,您需要5列5列。所以,
int height = 5;
int width = 2*height - 1;
即使我不确定drawing.setPoint(i, x, myChar);
做了什么,我认为这个例子会让你前进。我将基于String
来构建char
。
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 :(得分:1)
有很多方法可以解决这个问题,你已经看到了一个逐行绘制图片的答案。
我将假设您已经有了创建char[][]
的例程并将该数组数组中的字符打印到屏幕上。看起来你已经有了一个setPoint()
方法,可以将一个点放入结构中。
作为一名初学者,我认为不能帮助您获得解决方案。你需要指出正确的方向来解决它。
很多经验丰富的编码器现在都使用测试驱动设计,您可以从中学习:从一个简单的案例开始,为此创建测试,使测试通过,重复更多测试,直到没有更多的测试要写。最终你应该学习像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)
绘制三行三角形,然后您可以通过使用循环来改善它。