如何使用public void testDistanceBetween_AD

时间:2016-05-11 15:09:00

标签: java arrays eclipse arraylist system.out

我正在为这个问题提供我的源代码,因为我无法在TrainsTest类中进行简单的系统打印,这让我感到很沮丧。正如你所看到的那样,我遇到了在TrainsTest类中打印vaule以解决以下方法的问题;

public void testDistanceBetween_ABC public void testDistanceBetween_AD public void testDistanceBetween_ADC public void testDistanceBetween_AEBCD public void testDistanceBetween_AED public void numRoutesWithin_CC30 public void testEquals

任何帮助将不胜感激!谢谢!

以下是我的节点类

package com.utsavized.trains;

public class Node {
public String name;
public boolean visited;

public Node(String name) {
    this.name = name;
    this.visited = false;
}

@Override
public boolean equals(Object b) {
    if (b == null || b.getClass() != getClass()) {
        return false;
    }
    Node bx = (Node)b;
    return this.name.equals(bx.name);
}

@Override
public int hashCode() {
    if(this.name == null) return 0;
    return this.name.hashCode();
}
}

以下是我的Edge类

public class Edge {

public Node origin;

public Node destination;

public int weight;

public Edge next;

public Edge(Node origin, Node destination, int weight) {
    this.origin         = origin;
    this.destination    = destination;
    this.weight         = weight;
    this.next       = null;
}

public Edge next(Edge edge) {
    this.next = edge;
    return this;
}
}

以下是我的路线类

import java.util.ArrayList;
import java.util.Hashtable;

public class Routes {
public Hashtable<Node, Edge> routeTable;

public Routes() {
    this.routeTable = new Hashtable<Node, Edge>();
}


public int distanceBetween(ArrayList<Node> cities) throws Exception {
    /*There is no distance between
     * no cities or 1 city*/
    if(cities.size() < 2)
        return 0;
    int distance, depth, i;
    distance = depth = i = 0;

    /* For each city in the list,
     * we check if entry exists in our
     * hash table.
     */
    while(i < cities.size() - 1) {
        if(this.routeTable.containsKey(cities.get(i))) {
            Edge route = this.routeTable.get(cities.get(i));
            /*If key exists, we check if route from key to next
             * city exists. We add the distance, and maintain a
             * depth count
             */
            while(route != null) {
                if(route.destination.equals(cities.get(i + 1))) {
                    distance += route.weight;
                    depth++;
                    break;
                }
                route = route.next;
            }
        }
        else
            throw new Exception("NO SUCH ROUTE");
        i++;
    }
    /*If edge depth is not equal to vertex - 1,
     * then it is safe to assume that one ore more
     * routes do not exist
     */
    if(depth != cities.size() - 1)
        throw new Exception("NO SUCH ROUTE");

    return distance;
}

/*
 * Number of stops;
 * Wrapper for recursive function
 */
public int numStops(Node start, Node end, int maxStops) throws Exception{
    //Wrapper to maintain depth of traversal
    return findRoutes(start, end, 0, maxStops);
}

/*
 * Finds number of stops from start to end,
 * with a maximum of maxStops and the depth
 * limit.
 */
private int findRoutes(Node start, Node end, int depth, int maxStops) throws Exception{
    int routes = 0;
    //Check if start and end nodes exists in route table
    if(this.routeTable.containsKey(start) && this.routeTable.containsKey(end)) {
        /*
         * If start node exists then traverse all possible
         * routes and for each, check if it is destination
         * If destination, and number of stops within 
         * allowed limits, count it as possible route.
         */
        depth++;
        if(depth > maxStops)        //Check if depth level is within        limits
            return 0;
        start.visited = true;       //Mark start node as visited
        Edge edge = this.routeTable.get(start);
        while(edge != null) {
            /* If destination matches, we increment route
             * count, then continue to next node at same depth
             */
            if(edge.destination.equals(end)) {
                routes++;
                edge = edge.next;
                continue;
            }
            /* If destination does not match, and
             * destination node has not yet been visited,
             * we recursively traverse destination node
             */
            else if(!edge.destination.visited) {
                routes += findRoutes(edge.destination, end, depth,                                                        maxStops);
                depth--;
            }
            edge = edge.next;
        }
    }
    else
        throw new Exception("NO SUCH ROUTE");

    /*
     * Before exiting this recursive stack level,
     * we mark the start node as visited.
     */
    start.visited = false;
    return routes;
}

/*
 * Shortest route;
 * Wrapper for recursive function
 */
public int shortestRoute(Node start, Node end) throws Exception {
    //Wrapper to maintain weight
    return findShortestRoute(start, end, 0, 0);

}

/*
 * Finds the shortest route between two nodes
 */
private int findShortestRoute(Node start, Node end, int weight, int shortestRoute) throws Exception{
    //Check if start and end nodes exists in route table
    if(this.routeTable.containsKey(start) && this.routeTable.containsKey(end)) {
        /*
         * If start node exists then traverse all possible
         * routes and for each, check if it is destination
         */
        start.visited = true;       //Mark start node as visited
        Edge edge = this.routeTable.get(start);
        while(edge != null) {
            //If node not already visited, or is the destination, increment weight
            if(edge.destination == end || !edge.destination.visited)
                weight += edge.weight;

            /* If destination matches, we compare
             * weight of this route to shortest route
             * so far, and make appropriate switch
             */
            if(edge.destination.equals(end)) {
                if(shortestRoute == 0 || weight < shortestRoute)
                    shortestRoute = weight;
                start.visited = false;
                return shortestRoute;           //Unvisit node and return shortest route
            }
            /* If destination does not match, and
             * destination node has not yet been visited,
             * we recursively traverse destination node
             */
            else if(!edge.destination.visited) {
                shortestRoute = findShortestRoute(edge.destination, end, weight, shortestRoute);
                //Decrement weight as we backtrack
                weight -= edge.weight;
            }
            edge = edge.next;
        }
    }
    else
        throw new Exception("NO SUCH ROUTE");

    /*
     * Before exiting this recursive stack level,
     * we mark the start node as visited.
     */
    start.visited = false;
    return shortestRoute;

}

/*
 * Shortest route;
 * Wrapper for recursive function
 */
public int numRoutesWithin(Node start, Node end, int maxDistance) throws Exception {
    //Wrapper to maintain weight
    return findnumRoutesWithin(start, end, 0, maxDistance);
}

/*
 * Finds the shortest route between two nodes
 */
private int findnumRoutesWithin(Node start, Node end, int weight, int maxDistance) throws Exception{
    int routes = 0;
    //Check if start and end nodes exists in route table
    if(this.routeTable.containsKey(start) && this.routeTable.containsKey(end)) {
        /*
         * If start node exists then traverse all possible
         * routes and for each, check if it is destination
         */
        Edge edge = this.routeTable.get(start);
        while(edge != null) {
            weight += edge.weight; 
            /* If distance is under max, keep traversing
             * even if match is found until distance is > max
             */
            if(weight <= maxDistance) {
                if(edge.destination.equals(end)) {
                    routes++;
                    routes += findnumRoutesWithin(edge.destination, end, weight, maxDistance);
                    edge = edge.next;
                    continue;
                }
                else {
                    routes += findnumRoutesWithin(edge.destination, end, weight, maxDistance);
                    weight -= edge.weight;  //Decrement weight as we backtrack
                }
            }
            else 
                weight -= edge.weight;

            edge = edge.next;
        }
    }
    else
        throw new Exception("NO SUCH ROUTE");

    return routes;

}   

}

以下是我的TrainsTest课程

    package com.utsavized.trains;



    import static org.junit.Assert.*;

    import java.util.ArrayList;
    import java.util.stream.Collectors;

    import org.junit.BeforeClass;
    import org.junit.Test;

    public class TrainsTest {
static Routes graph;
static Node a, b, c, d, e;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
    graph = new Routes(); //Build graph

    a = new Node("A");
    b = new Node("B");
    c = new Node("C");
    d = new Node("D");
    e = new Node("E");

    /*Input given in programming challenge
    Graph: AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7*/
    graph.routeTable.put(a, new Edge(a, b, 5).next(new Edge(a, d, 5).next(new Edge(a, e, 7))));
    graph.routeTable.put(b, new Edge(b, c, 4));
    graph.routeTable.put(c, new Edge(c, d, 8).next(new Edge(c, e, 2)));
    graph.routeTable.put(d, new Edge(d, c, 8).next(new Edge(d, e, 6)));
    graph.routeTable.put(e, new Edge(e, b, 3));
}

@Test
public void testDistanceBetween_ABC() throws Exception {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(b);
    route.add(c);
    //System.out.println(a);
    assertEquals(9, graph.distanceBetween(route));      

}

@Test
public void testDistanceBetween_AD() throws Exception {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(d);
    assertEquals(5, graph.distanceBetween(route));
}

@Test
public void testDistanceBetween_ADC() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(d);
    route.add(c);
    assertEquals(13, graph.distanceBetween(route));
}

@Test
public void testDistanceBetween_AEBCD() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(e);
    route.add(b);
    route.add(c);
    route.add(d);
    assertEquals(22, graph.distanceBetween(route));
}

@Test(expected=Exception.class)
public void testDistanceBetween_AED() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(e);
    route.add(d);
    assertEquals(-1, graph.distanceBetween(route));
}

@Test
public void testNumStops_CC3() throws Exception {
    int numStops = graph.numStops(c, c, 3);
    assertEquals(2, numStops);
}

@Test
public void testNumStops_AC4() throws Exception {
    int numStops = graph.numStops(a, c, 4);
    assertEquals(4, numStops);
}

@Test
public void testShortestRoute_AC() throws Exception {
    int shortestRoute = graph.shortestRoute(a, c);
    assertEquals(9, shortestRoute);
    System.out.println(shortestRoute);  
}

@Test
public void testShortestRoute_BB() throws Exception {
    int shortestRoute = graph.shortestRoute(b, b);
    assertEquals(9, shortestRoute);
}

@Test
public void numRoutesWithin_CC30() throws Exception {
    int numRoutesWithin = graph.numRoutesWithin(c, c, 30);
    assertEquals(7, numRoutesWithin);
}

@Test
public void testEquals() {
    Node a1 = new Node("A");
    Node a2 = new Node("A");
    Node b = new Node("B");

    assertEquals(true, a1.equals(a2));
    assertEquals(false, a1.equals(b));
    assertEquals(true, (new Node("Test").equals(new Node("Test"))));
}

}

您好我正在尝试打印a,b和c的值。正如您所看到的,我在路由中使用System out println,但它不会输出任何内容。有没有办法输出结果而不需要对方法进行太多修改?

public void testDistanceBetween_ADC() throws Exception  {
    ArrayList<Node> route = new ArrayList<Node>(); 
    route.add(a);
    route.add(d);
    route.add(c);
    assertEquals(13, graph.distanceBetween(route));
    System.out.println(route);
}

我不确定是否应该输出变量&#39; route&#39;或者如果我需要添加另一个小方法。任何帮助将不胜感激我知道这是一件我想做的事情,但由于某种原因它不适合我。

非常感谢!!

2 个答案:

答案 0 :(得分:0)

在编辑到我的原始答案中,您的distanceBetween-method的内部while循环中似乎存在错误。

如果路由包含节点A,B,C,它将计算节点A,获取边缘到节点B,然后在内部循环中,它将总结边缘的权重。之后,您致电break。这将打破while循环

如果你真的想打破循环,你应该看看如何在java中标记循环:Labeled Loops

我不喜欢使用带标签的循环,因为它有时会变得有点混乱。在您的情况下,只需使用:

if(route.destination.equals(cities.get(i + 1))) {
                distance += route.weight;
                depth++;
} else {
            route = route.next;
}

//do further (error) handling

目前,还不清楚你想用深度变量做什么。在您的实现中,它将始终抛出异常,因为您在找到第一个路径后断开循环,然后总结深度,然后检查深度是否具有特定大小。因此,在大于2个节点的路由中,此异常将始终飞行。

对于一个最小的例子,仅使用距离可能很有用:

       //...
        Edge route = this.routeTable.get(cities.get(i));
        int newDistance = distance;
        /*If key exists, we check if route from key to next
         * city exists. We add the distance, and maintain a
         * depth count
         */
        while(route != null) {
            if(route.destination.equals(cities.get(i + 1))) {
                newDistance += route.weight;
               // depth++;
            } else {
                route = route.next;
            }
        }

        if(newDistance == distance) {
             //the distance didnt change - it seems there was no route found, throw Exception or expand the graph or whatever
        } else {
             distance = newDistance; //now you have the distance for the next loop-run
        }

答案 1 :(得分:0)

您有3个选项

实现toString()

如果Node类是您的来源的一部分,只需添加toString方法

public String toString(){
    return name;
}

覆盖节点

如果Node类是外部库的一部分但不是最终的,则可以覆盖该节点并实现toString()使用overriden类而不是supahupe建议。

使用Stream&amp;地图显示

如果您无法像Supahupe建议的那样覆盖节点,您可以使用可公开访问的name字段并将其映射到新的字符串列表并将其打印出来

System.out.println(route.stream().map(n -> n.name).collect(Collectors.toList()));

或者你可以为你的节点创建一个装饰器类,其唯一目的就是将它打印出来,aproach与stream相同

...stream().map(n -> new NodeDecorator(n))...