我正在编写一个将Vertex对象添加到数组的方法。我需要检查我添加的顶点是否已存在于数组中。我不确定我哪里出错了。这是我的方法:
public void addVertex(Vertex v) {
if (activeVertices >= maxVertices) {
System.out.println("Graph full");
return;
}
for(int i=1; i<vertices.length; i++) {
if(vertices[i] != vertices[i-1]){
vertices[activeVertices] = v; // add vertex to list of vertices
v.graphIndex = activeVertices; // record index of vertex in graph
activeVertices++; // increment vertex count
}
}
}
顶点类:
public class Vertex {
public String name;
public int graphIndex; // index of adjacency matrix position of node in graph
public Vertex (String s) {
name = s;
graphIndex = -1; // invalid position by default
}
public String toString() {
return name;
}
}
包含addVertex()方法的类:
public class Graph {
private int maxVertices;
private Vertex[] vertices; // array of nodes
private int[][] edges; // adjacency matrix
int activeVertices;
public Graph(int maxSize) {
maxVertices = maxSize;
vertices = new Vertex[maxVertices];
activeVertices = 0;
}
public void addVertex(Vertex v) {
if (activeVertices >= maxVertices) {
System.out.println("Graph full");
return;
}
for(int i=1; i<vertices.length; i++) {
if(vertices[i] != vertices[i-1]){
vertices[activeVertices] = v; // add vertex to list of vertices
v.graphIndex = activeVertices; // record index of vertex in graph
activeVertices++; // increment vertex count
}
}
}
public void addEdge(Vertex v1, Vertex v2, int w) {
edges[v1.graphIndex][v2.graphIndex] = w;
edges[v2.graphIndex][v1.graphIndex] = w;
}
public Graph minimumSpanningTree() {
Graph mst = new Graph(maxVertices); // create new graph
int[] set = new int[activeVertices];
for (int i=0; i<activeVertices; i++) { // copy nodes to graph
mst.addVertex(vertices[i]);
set[i]=i; // assign each node to its own set
}
PriorityQueue q = new PriorityQueue(maxVertices*maxVertices); // create priority queue
for (int i=0; i<activeVertices; i++) { // copy edges to queue
for (int j=0; j<activeVertices; j++) {
if (edges[i][j]!=0) {
q.enqueue(new Edge(vertices[i],vertices[j],edges[i][j]));
}
}
}
while (!q.isEmpty()) { // iterate over all edges in priority order
Edge e = q.dequeue(); // consider next edge
if (set[e.source.graphIndex]!=set[e.destination.graphIndex]) { // skip edges not connecting different sets
mst.addEdge(e.source, e.destination, e.weight); // add edge to MST
System.out.println("adding "+e);
int setToMerge=set[e.destination.graphIndex]; // rename nodes from "other" set
for (int i=0; i<activeVertices; i++) {
if (set[i]==setToMerge) { // find nodes from "other" set
set[i]=set[e.source.graphIndex]; // reassign nodes
}
}
}
}
return mst;
}
public void print() {
System.out.format(" ");
for (int i=0; i<activeVertices; i++) {
System.out.format("%3s ", vertices[i].name);
}
System.out.format("\n");
for (int j=0; j<activeVertices; j++) {
System.out.format("%3s ", vertices[j].name);
for (int i=0; i<activeVertices; i++) {
System.out.format("%3d ", edges[i][j]);
}
System.out.format("\n");
}
}
}
答案 0 :(得分:1)
首先,您应该使用equals
而不是==
。您应该在equals
课程中编写正确的Vertex
方法(使用Google查找大量有关如何执行此操作的教程)。
例如,如果您希望两个Vertex对象只有在它们的名称相同时才被认为是相同的,那么您的equals方法将如下所示:
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(obj instanceof Vertex) {
Vertex otherVertex = (Vertex) obj;
if(this.name.equals(otherVertex.name)) {
return true;
}
}
return false;
}
如果您还想比较graphIndex
,那么您还需要在equals
方法中进行检查。
假设您的equals
类中有一个正确的Vertex
方法,最简单的解决方案是使用来自Apache Commons库的ArrayUtils.contains
方法(Apache Commons有很多有用的东西)方法,可以节省你很多时间。你应该检查出来)。此方法接受一个数组和一个Object,并检查数组是否包含该对象。
答案 1 :(得分:0)
您始终针对vertices[1]
检查vertices[0]
并根据结果进行添加。你没有检查v
,也没有查看整个数组。
如果==
检查(身份,而不是等同)真的是你想要的,那么:
public void addVertex(Vertex v) {
if (activeVertices >= maxVertices) {
System.out.println("Graph full");
return;
}
for(int i=0; i<vertices.length; i++) {
if(vertices[i] == v){
// Already have it
return;
}
}
vertices[activeVertices] = v; // add vertex to list of vertices
v.graphIndex = activeVertices; // record index of vertex in graph
activeVertices++; // increment vertex count
}
如果您想要等效,请替换
if(vertices[i] == v){
与
if(v.equals(vertices[i])){
附注:根据您拥有activeVertices
变量,我怀疑您使用ArrayList<Vertex>
而不是Vertex[]
可能会更好。这也会为您提供contains
方法(使用equals
),它可以替换您的循环(如果您想要equals
,而不是==
,请检查)
答案 2 :(得分:0)
每当您编写值类时,即表示某事物的值或数量的类时,您应始终为您的类重写以下方法:
并非所有类都是值类。有些代表系统资源,有些代表行为或进程,但只要将类编写为数据集的抽象,就应该考虑编写上述方法。
原因很简单。虽然Java原语只具有价值,但Java引用类型(包括您自己编写的所有类的实例)都具有值值和位置。这赋予引用类型相等和同一性的属性,它们是非常不同的。
默认情况下,Object类中的equals()方法执行身份比较, NOT 执行相等比较......这也是一件好事。因为Object的任何子类可能具有截然不同的“如何将实例视为相等”的概念,所以没有直接的方法可以使用一个超类方法来测试任意Java对象的相等性。相比之下,测试身份总是直截了当的。如果任何两个引用指示相同的位置,则它们的对象是相同的。这体现了不同的平等和认同概念。
您需要能够测试您的Vertex实例是否相等以及不它们是否相同。因此,您确实需要覆盖equals(Object o)方法。如果你也覆盖hashCode()(你应该),那么你可以将你的顶点存储在一个HashSet中,这样可以保证两个顶点不相等。