Java 如何从drawSquare方法中删除递归并获得完全相同的结果?
我需要从drawSquare方法中删除递归。在从该方法中删除递归之后,我还需要做很多事情,但是剩下的事情我可以自己解决。我真的需要一个工作的解决方案,不用递归就能完成同样的事情,剩下的我会解决的 下面是我如何制作Square类的:Java 如何从drawSquare方法中删除递归并获得完全相同的结果?,java,recursion,coordinates,computer-science,square,Java,Recursion,Coordinates,Computer Science,Square,我需要从drawSquare方法中删除递归。在从该方法中删除递归之后,我还需要做很多事情,但是剩下的事情我可以自己解决。我真的需要一个工作的解决方案,不用递归就能完成同样的事情,剩下的我会解决的 下面是我如何制作Square类的: import java.awt.Color; public class Square { final int BLACK = Color.BLACK.getRGB(); final int WHITE = Color.WHITE.getRGB();
import java.awt.Color;
public class Square {
final int BLACK = Color.BLACK.getRGB();
final int WHITE = Color.WHITE.getRGB();
protected int center_x;
protected int center_y;
protected int side;
protected int color;
protected Square parentSquare;
public Square(){
this.center_x = 0;
this.center_y = 0;
this.side = 0;
this.color = WHITE;
this.parentSquare = null;
}
public Square(int center_x,int center_y,int side,int color){
this.center_x = center_x;
this.center_y = center_y;
this.side = side;
this.color = color;
this.parentSquare = null;
}
public Square(int center_x,int center_y,int side,int color,Square parentSquare){
this.center_x = center_x;
this.center_y = center_y;
this.side = side;
this.color = color;
this.parentSquare = parentSquare;
}
public void setX(int center_x){
this.center_x = center_x;
}
public int getX(){
return center_x;
}
public void setY(int center_y){
this.center_x = center_y;
}
public int getY(){
return center_y;
}
public void setSide(int side){
this.side = side;
}
public int getSide(){
return side;
}
public void setColor(int color){
this.color = color;
}
public int getColor(){
return color;
}
public void setParent(Square parentSquare){
this.parentSquare = parentSquare;
}
public Square getParent(){
return parentSquare;
}
}
这是原始的Tsquare.java,它生成从每个正方形4个角分支到边=0的正方形分形:(完整的Tsquare.java类修改为使用正方形对象)
导入java.awt.image.*;
导入java.awt.Color;
导入java.io.*;
导入javax.imageio.*;
导入java.util.*;
公共类广场{
静态final int SIDE=1000;//图像是X侧
静态BuffereImage=新的BuffereImage(SIDE,SIDE,BuffereImage.TYPE_INT_RGB);
静态最终int-WHITE=Color.WHITE.getRGB();
静态final int BLACK=Color.BLACK.getRGB();
静态扫描仪kbd=新扫描仪(System.in);
公共静态void main(字符串[]args)引发IOException{
String fileOut=“helloSquares.png”;
System.out.print(“输入(x,y)坐标,坐标之间留有空格:”;
int x=kbd.nextInt();
int y=kbd.nextInt();
System.out.println(x+,“+y);//TESTLINE TESTLINE TESTLINE
//使图像变黑
对于(int i=0;i if(square.side这里有一个使用ArrrayDeque()的实现
值得将ArrayQue与其他一些Java类型进行比较:
a) 堆栈是一个接口,api页()说
Deque接口及其实现提供了一组更完整、更一致的后进先出堆栈操作,应该优先于此类使用
b) 我最初是使用熟悉的ArrayList编写的,它使用Square=squares.remove(0);
而不是pop
。我很惊讶这个ArrayQue实现似乎比ArrayList快得多(我没有运行任何正式的基准测试)
private static void drawSquare(方形startSquare){
Deque squares=新ArrayDeque(400000);
正方形。推(开始正方形);
而(!squares.isEmpty()){
Square=squares.pop();
系统输出打印LN(方形);
//正方形的中心是x,y边的长度是s
如果(square.side>0){//基本情况
//定角
int left=square.center_x-(square.side/2);
int top=方形中心(方形侧面/2);
int right=square.center_x+(square.side/2);
int bottom=square.center_y+(square.side/2);
int newColor=square.color-100000;
addSquare(正方形,左侧,顶部,正方形。侧面/2,新颜色);
addSquare(正方形,左侧,底部,正方形。侧面/2,新颜色);
addSquare(正方形,右侧,顶部,正方形。侧面/2,新颜色);
addSquare(正方形,右,下,正方形。侧/2,新颜色);
}
}
}
专用静态void addSquare(三角形正方形、整数x、整数y、整数边、整数颜色){
//强烈建议使用此“如果”语句!
//如果(侧>0){
方块。推(新方块(x,y,边,颜色));
// }
}
正如我在评论中所指出的,不创建大小为0的正方形是非常值得的,而不是创建它们并在轮到它们时简单地忽略它们。对于基于递归的操作也是如此,但对于这些非基于递归的操作尤其如此,因为大量的正方形实际上会消耗内存和时间处理时间。如果我们想在不影响速度的情况下提高可读性,我建议首先对Square
进行一些添加:
public int half() {
return side/2;
}
public int left() {
return center_x - half();
}
public int top() {
return center_y - half();
}
public int right() {
return center_x + half();
}
public int bottom() {
return center_y + half();
}
public void draw(BufferedImage image) {
int left = left();
int top = top();
int right = right();
int bottom = bottom();
for (int i = left; i < right; i++){
for (int j = top; j < bottom; j++){
image.setRGB(i, j, color);
}
}
} //End Square
既然Square
正在处理所有方形的东西,那么分形代码就更容易看了
private static void drawFractal(Square square, BufferedImage image){
Queue<Square> squares = new LinkedList<>();
squares.add(square);
while (squares.size() > 0) {
//Consume
square = squares.remove();
//Produce
int half = square.half();
if (half > 2) {
int left = square.left();
int top = square.top();
int right = square.right();
int bottom = square.bottom();
int newColor = square.color - 100000;
squares.add(new Square(left, top, half, newColor));
squares.add(new Square(left, bottom, half, newColor));
squares.add(new Square(right, top, half, newColor));
squares.add(new Square(right, bottom, half, newColor));
}
square.draw(image);
}
}
protected static void saveImage(BufferedImage image) throws IOException {
String fileOut = "helloSquares.png";
File outputfile = new File(fileOut);
ImageIO.write(image, "jpg", outputfile);
}
} //End FractalSquareIterative
private static void drawFractal(正方形,buffereImage图像){
Queue squares=新链接列表();
正方形。添加(正方形);
while(squares.size()>0){
//消耗
正方形=正方形。删除();
//产生
int half=平方。half();
如果(一半>2){
int left=square.left();
int top=square.top();
int right=square.right();
int bottom=square.bottom();
int newColor=square.color-100000;
正方形。添加(新正方形(左、上、半、新颜色));
添加(新方块(左、下、半、新颜色));
添加(新正方形(右、上、半、新颜色));
添加(新方块(右、下、半、新颜色));
}
正方形。绘制(图像);
}
}
受保护的静态void saveImage(BuffereImage)引发IOException{
String fileOut=“helloSquares.png”;
文件输出文件=新文件(文件输出);
写入(图像,“jpg”,输出文件);
}
}//结束分形
可靠的速度比递归版本快,但在这种大小下不会明显加快
如果你想看一看我的单元测试,你会发现它们。你可以使用堆栈或队列模拟递归。但我认为这会降低代码的可读性。实际上,我要处理的程序的下一部分是在链接堆栈中实现相同的东西。如果这是简化操作的方法,我将非常感激
public int half() {
return side/2;
}
public int left() {
return center_x - half();
}
public int top() {
return center_y - half();
}
public int right() {
return center_x + half();
}
public int bottom() {
return center_y + half();
}
public void draw(BufferedImage image) {
int left = left();
int top = top();
int right = right();
int bottom = bottom();
for (int i = left; i < right; i++){
for (int j = top; j < bottom; j++){
image.setRGB(i, j, color);
}
}
} //End Square
package com.stackoverflow.candied_orange;
import java.awt.image.*;
import java.awt.Color;
import java.io.*;
import javax.imageio.*;
import java.util.*;
public class FractalSquareIterative {
public static void main(String[] args) throws IOException{
final int SIDE = 1000; // image is SIDE X SIDE
BufferedImage image = new BufferedImage(SIDE,SIDE,BufferedImage.TYPE_INT_RGB);
drawImage(SIDE, image);
saveImage(image);
}
//Removed IO to enable unit testing
protected static void drawImage(final int SIDE, BufferedImage image) {
final int BLACK = Color.BLACK.getRGB();
final int WHITE = Color.WHITE.getRGB();
final int HALF = SIDE / 2;
//Draw background on whole image
new Square(HALF, HALF, SIDE, BLACK).draw(image);
//Draw foreground starting with centered half sized square
Square square = new Square(HALF, HALF, HALF, WHITE);
drawFractal(square, image);
}
private static void drawFractal(Square square, BufferedImage image){
Queue<Square> squares = new LinkedList<>();
squares.add(square);
while (squares.size() > 0) {
//Consume
square = squares.remove();
//Produce
int half = square.half();
if (half > 2) {
int left = square.left();
int top = square.top();
int right = square.right();
int bottom = square.bottom();
int newColor = square.color - 100000;
squares.add(new Square(left, top, half, newColor));
squares.add(new Square(left, bottom, half, newColor));
squares.add(new Square(right, top, half, newColor));
squares.add(new Square(right, bottom, half, newColor));
}
square.draw(image);
}
}
protected static void saveImage(BufferedImage image) throws IOException {
String fileOut = "helloSquares.png";
File outputfile = new File(fileOut);
ImageIO.write(image, "jpg", outputfile);
}
} //End FractalSquareIterative