【问题标题】:Search method of Stack class always returning -1Stack类的搜索方法总是返回-1
【发布时间】:2013-02-23 12:18:52
【问题描述】:

我有这个类来保存两个值:

public class Coord {

    public int x; 
    public int y;

    public Coord(int x, int y) { 
        this.x = x; 
        this.y = y; 
    }
}

我正在尝试在深度优先搜索算法中使用它:

x = this.move_to_x;
y = this.move_to_y;

Coord stack = new Coord(0, 0);

Stack<Coord> start = new Stack<Coord>();
Stack<Coord> visited = new Stack<Coord>();

start.push(stack);
visited.push(stack);

while (!start.empty()) {
    Coord tmp = (Coord)start.pop();

    int j,k;

    j = tmp.x;
    k = tmp.y;

    // there is only 8 possible ways to go (the neighbors)
    for (int a = -1; a < 2; a++) {
        tmp.x = j + a;

        for (int b = -1; b < 2; b++) {
            if (a == 0 && b == 0) {
                continue;
            }

            tmp.y = k + b;

            if (tmp.x < 0 || tmp.y < 0) {
                continue;
            }

            if (tmp.x > 5 || tmp.y > 5) {
                continue;
            }

            if (tmp.x == x && tmp.y == y) {
                System.out.println("end!");
                return;
            }

            Coord push = new Coord(tmp.x, tmp.y);

            System.out.println("visited: " + visited);

            if (visited.search(push) == -1) {
                System.out.println("added x " + push.x + " y " + push.y
                        + " " + visited.search(push));

                start.push(push);
                visited.push(push);
            } else {
                System.out.println("visited x " + tmp.x + " y " + tmp.y
                        + " index  " + visited.search(push));
            }
        }
    }
}

问题是visited.search 方法总是返回-1。这是日志:

visited: [Agent.ExampleAgent.Coord@1af6a711]
added x 0 y 1 -1
visited: [Agent.ExampleAgent.Coord@1af6a711, Agent.ExampleAgent.Coord@1c727896]
added x 1 y 0 -1
visited: [Agent.ExampleAgent.Coord@1af6a711, Agent.ExampleAgent.Coord@1c727896, Agent.ExampleAgent.Coord@5fbd8c6e]
added x 1 y 1 -1
visited: [Agent.ExampleAgent.Coord@1af6a711, Agent.ExampleAgent.Coord@1c727896, Agent.ExampleAgent.Coord@5fbd8c6e, Agent.ExampleAgent.Coord@427a8ba4]
added x 0 y 0 -1
visited: [Agent.ExampleAgent.Coord@1af6a711, Agent.ExampleAgent.Coord@1c727896, Agent.ExampleAgent.Coord@5fbd8c6e, Agent.ExampleAgent.Coord@427a8ba4, Agent.ExampleAgent.Coord@262f6be5]
added x 0 y 1 -1
visited: [Agent.ExampleAgent.Coord@1af6a711, Agent.ExampleAgent.Coord@1c727896, Agent.ExampleAgent.Coord@5fbd8c6e, Agent.ExampleAgent.Coord@427a8ba4, Agent.ExampleAgent.Coord@262f6be5, Agent.ExampleAgent.Coord@199d4a86]

请注意,添加到访问堆栈的第一个元素是(0,1),但是当搜索(0,1) 时,该方法稍后会返回-1

【问题讨论】:

    标签: java stack depth-first-search


    【解决方案1】:

    如果参数的 x 和 y 等于对象的 x 和 y 值,您需要重写 equals() 方法,以便它返回 true

    您还应该重写hashCode() 方法,使其与equals() 方法“一致”。

    【讨论】:

    • 我认为我的equals实现是正确的,hashCode呢? pastebin.com/9WfVcP7b
    • hashCode 总是返回 1 使得搜索方法总是返回 -1。看起来不太对劲,
    • @FredericoSchardong 你的Coord 类是否有以下内容?@Override public boolean equals(Object other) 和 @Override public int hashCode()
    • @FredericoSchardong 你可能会发现this topic 很有用。
    • @FredericoSchardong 尝试用这个单行替换你的hashCode() 实现:return x*17 + y*31;
    【解决方案2】:

    (我想我会发布一个答案,概述我们在聊天讨论中取得的进展)

    假设Coord类的状态如下:

    public class Coord {
    
        public int x; 
        public int y;
    
        public Coord(int x, int y) { 
            this.x = x; 
            this.y = y; 
        }
    
        @Override
        public boolean equals(Object obj){
    
            if (obj == null)
                return false;
            if (obj.getClass() != Coord.class)
                return false;
            if (obj == this)
                return true;
    
            Coord a = (Coord)obj;
            return (a.x == this.x && a.y == this.y);
        }
    
        @Override
        public int hashCode() {
            return x*17 + y*31;
        }
    
        @Override
        public String toString() {
            return "("+x+", "+y+")";
        }
    }
    

    ...实现:

    • equals() 因为这是堆栈搜索使用的,根据它的 Javadoc
    • hashCode() 作为最佳实践,伴随equals()
    • toString() 用于更清晰的诊断输出

    我们的想法是独立于代码的其余部分来测试堆栈搜索的功能。如果我们可以证明堆栈搜索功能正常,那么问题就出在其他地方。

    证明堆栈搜索可以使用测试类来完成,例如这个:

    public class CoordTest {
    
    public static void main(String[] args) {
        System.out.println("Running tests...");
    
        System.out.println("Testing: equals");
        Coord c1a = new Coord(2,3);
        Coord c1b = new Coord(2,3);
        check(c1a.equals(c1b));
    
        System.out.println("Testing: not equals"); 
        Coord c2a = new Coord(2,3);
        Coord c2b = new Coord(6,8);
        Coord c2c = new Coord(2,8); 
        Coord c2d = new Coord(6,3);
        check(!c2a.equals(c2b));
        check(!c2a.equals(c2c));
        check(!c2a.equals(c2d));
    
        System.out.println("Testing: not found in empty stack"); 
        Stack<Coord> stack1 = new Stack<Coord>();
        int result1 = stack1.search(c1a);
        check(result1 == -1);
    
        System.out.println("Testing: not found in non-empty stack"); 
        Stack<Coord> stack2 = new Stack<Coord>();
        stack2.push(new Coord(4,5));
        stack2.push(new Coord(6,7));
        int result2 = stack2.search(c1a);
        check(result2 == -1);
    
        System.out.println("Testing: found in non-empty stack"); 
        Stack<Coord> stack3 = new Stack<Coord>();
        stack3.push(new Coord(4,5));
        stack3.push(new Coord(3,1));
        stack3.push(new Coord(6,7));        
        int result3 = stack3.search(new Coord(3,1));
        check(result3 == 2);        
    
        System.out.println("All tests completed successfully.");
    }
    
    private static void check(boolean condition) {
        if (!condition) {
            throw new RuntimeException("Condition failed!");
        }
    }
    
    }
    

    输出:

    Running tests...
    Testing: equals
    Testing: not equals
    Testing: not found in empty stack
    Testing: not found in non-empty stack
    Testing: found in non-empty stack
    All tests completed successfully.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      • 2020-01-07
      • 2016-02-13
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      相关资源
      最近更新 更多