我正在为这个问题提供我的源代码,因为我无法在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;或者如果我需要添加另一个小方法。任何帮助将不胜感激我知道这是一件我想做的事情,但由于某种原因它不适合我。
非常感谢!!答案 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个选项
如果Node
类是您的来源的一部分,只需添加toString
方法
public String toString(){
return name;
}
如果Node
类是外部库的一部分但不是最终的,则可以覆盖该节点并实现toString()
使用overriden类而不是supahupe建议。
如果您无法像Supahupe建议的那样覆盖节点,您可以使用可公开访问的name
字段并将其映射到新的字符串列表并将其打印出来
System.out.println(route.stream().map(n -> n.name).collect(Collectors.toList()));
或者你可以为你的节点创建一个装饰器类,其唯一目的就是将它打印出来,aproach与stream相同
...stream().map(n -> new NodeDecorator(n))...