Java 如何从drawSquare方法中删除递归并获得完全相同的结果?

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();

我需要从drawSquare方法中删除递归。在从该方法中删除递归之后,我还需要做很多事情,但是剩下的事情我可以自己解决。我真的需要一个工作的解决方案,不用递归就能完成同样的事情,剩下的我会解决的

下面是我如何制作Square类的:

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;iif(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