【问题标题】:Sierpinski carpet use a stack instead of recursion谢尔宾斯基地毯使用堆栈而不是递归
【发布时间】:2018-03-09 09:38:50
【问题描述】:

我已经实现了一个使用递归解决Sierpinski carpet 问题的解决方案。现在我想使用堆栈而不是递归方法来解决谢尔宾斯基地毯。我正在尝试将我的递归方法转换到堆栈中,但是当我从递归方法中推送变量时遇到了麻烦。这是我必须推送和弹出的一段代码 drawGasket(x + i * sub, y + j * sub, sub);

当您调用 drawGasket(0, 0, 729) 时,您应该会在屏幕上看到以下内容:

递归方法:

   public void drawGasket(int x, int y, int side) {
    int sub = side / 3; 

    //Draw center square
    g2d.fill(new Rectangle2D.Double(x + sub, y + sub, sub - 1, sub - 1));

    if(sub >= 3) {
        //Draw 8 surrounding squares
        for (int i = 0; i < 3; i++){
            for (int j = 0; j < 3; j++){
                if (j!=1 || i != 1)
                    drawGasket(x + i * sub, y + j * sub, sub);
            }
        }
    }
}

堆栈实现:

    public void stack (int x, int y, int side ){
    GenericStack<Integer> s = new GenericStack<>();

    int sub = side /3;
    g2d.fill(new Rectangle2D.Double(x + sub, y + sub, sub - 1, sub - 1));

    while (!s.isEmpty()){
        x=s.pop();
        if (sub >=3){
            for (int i = 0; i < 3; i++){
                for (int j = 0; j < 3; j++){    
                    if (j!=1 || i != 1){
                        int operation = x+i*sub;
                        s.push(operation);
                        int operation2 = y+j*sub;
                        s.push(operation2);
                        s.push(sub);
                    }
                }
            }
        }
    }
}

我的堆栈类:

public class GenericStack<T> {

private int size; // size
private Node<T> head; // node head

public GenericStack() { // constructor
    head = null; // head is null
    size = 0; // size is zero
}

public void push(T element) {
    if(head == null) { // if head is null
        head = new Node(element); // head is node 
    } else {
        Node<T> newNode = new Node(element);
        newNode.next = head;
        head = newNode;
    }

    size++;
}

public T pop() {
    if(head == null)
        return null;
    else {
        T topData = head.data;

        head = head.next;
        size--;

        return topData;
    }
}

public T top() {
    if(head != null)
        return head.data;
    else
        return null;
}

public int size() {
    return size;
}

public boolean isEmpty() {
    return size == 0;
}

private class Node<T> {
    private T data;
    private Node<T> next;

    public Node(T data) {
        this.data = data;
    }

}

【问题讨论】:

  • 我没有看到问题。
  • 问题(据我了解)是“如何编写我已经编写的递归解决方案的迭代(基于堆栈)版本?”

标签: java recursion stack


【解决方案1】:

如果您可以将递归版本描述为已经是基于堆栈的,那么您应该能够适当地翻译您的代码。如果您认为对drawGasket(x + i * sub, y + j * sub, sub); 的每次递归调用都将三个值推入堆栈,并且将drawGasket 方法“内部”的每个第一步都视为从该堆栈中弹出三个值,然后显式地打开和关闭这些相同的值您在迭代解决方案中的 GenericStack 应该遵循相同的模式。基本上,就像在递归解决方案中一样,您需要将连续的值推送、推送、推送到堆栈上,直到用完要推送的值;然后你需要从堆栈中弹出、弹出、弹出连续的值并“绘制”一个适合刚刚弹出的值的矩形,直到堆栈为空。

【讨论】:

  • 所以当我弹出方法时,我是否在 while 循环的开头执行它,对于递归参数,我是否将它们一一推送?
  • 我认为您将需要两个 while 循环,一个用于推送,一个用于弹出。 while(there are still items to push onto the stack)while(there are still items to pop off of the stack)。是的,你需要按照正确的顺序一个一个的推送,然后以“逆序”一个一个的弹出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
相关资源
最近更新 更多