我创建了自己的Node类和我自己的LinkedList类,我想构建一个函数来计算我的LinkedList中有多少个不同的Node。
我尝试使用此代码,但它不起作用:
for (int i = 0; i < quantityOfNode(); i++) {
boolean isDistinct = true;
for (int j = 0; j < i; j++) {
if (node.getInfo().equals(node.getNext().getInfo())) {
isDistinct = false;
}
}
if (isDistinct) {
nbDistinct++;
}
if (node.getNext().getNext() != null) {
node= node.getNext();
}
}
例如:
list.add(3);
list.add(2);
list.add(5);
list.add(3);
list.add(3);
list.add(8);
这是给我4个不同的节点,但我得到5,因为节点3被计算2次
现在我试图在我的j循环中使用第二个节点进行旅行并且对于相同的输入它现在给我2而不是4
这是我尝试过的新代码,但仍无效:
for (int i = 0; i < quantityOfNode(); i++) {
boolean isDistinct = true;
for (int j = 0; j < i; j++) {
if (node.getInfo().equals(node2.getInfo())) {
isDistinct = false;
}
if (node2.getNext() != null) {
node2 = node2.getNext();
}
}
if (isDistinct) {
nbDistinct++;
}
if (node.getNext() != null) {
node= node.getNext();
}
}
答案 0 :(得分:2)
您可以使用Set。
Set set = new HashSet();
Node cur = list.head;
while(cur != null) {
set.add(cur.getInfo());
cur = cur.getNext();
}
return set.size();
这不使用泛型,因为我不知道你有什么类型的getInfo。
或者,如果你不能使用一个集合,你应该试着摆脱你的'索引'变量(i和j)。您真的希望将应用程序逻辑集中在实际拥有的内容上,而不是隐式计算的值。您希望在当前节点变为空时停止,而不是在您前进一定次数时停止。如果那不合逻辑,请告诉我。
对于每个节点,检查之前的节点以查看该节点是否存在。我每次都从头开始,因为我不知道你是否有双重链接。无论哪种方式都是相同的复杂性,但在排序列表中,这不太理想。
Node cur = list.head; // for each node
int nbDistinct = 0;
while(cur != null) { // go until we're out of nodes
Node check = list.head; // check the first node
boolean isDistinct = true; // assume distinct
while(check != cur && isDistinct) { // stop if we found a match OR if our checker caught up to our current node
isDistinct |= !check.getInfo().equals(cur.getInfo()); // essentially "if(check.getInfo().equals(cur.getInfo()) isDistinct = true;"
check = check.getNext(); // advance the checker
}
if(isDistinct) nbDistinct++;
cur = cur.getNext(); // advance the current node
}
答案 1 :(得分:2)
第一个问题:
如果你的for循环被写成它不会超过链表的长度:
for (int i = 0; i < length(); i++) {
那为什么你需要这个?
if (node.getNext().getNext() != null) {
node= node.getNext();
}
特别是,此代码可能意味着在结束之前的节点被评估两次,因为超出它的节点是null
。它不一定会使你的算法错误,但它闻起来很糟糕,我不喜欢它。
第二个问题:
for (int j = 0; j < i; j++) {
if (node.getInfo().equals(node.getNext().getInfo())) {
isDistinct = false;
}
}
这是计算重复项的错误方法,因为您不存储和提前要比较的第二个节点的位置。尝试像
这样的东西 Node node2 = firstNode(); //idk what method gets the first node :)
for (int j = 0; j < i; j++) {
if (node.getInfo().equals(node2.getInfo())) {
isDistinct = false;
break; //optimization, stop as soon as we find a duplicate
}
node2 = node2.GetNext();
}
最后,每当遇到不起作用的代码时,请附加一个调试器,逐步执行它,并注意代码没有达到预期的效果。这将快速解决所有逻辑错误只是少量的观察。即使您无法访问调试器,也可以使用print
语句打印各种变量的值,并在某些代码分支执行时进行比较,并与预期的内容进行比较。
答案 2 :(得分:1)
你的j
循环没有向前迈步node
- 它始终在比较同一对节点,因此没有任何功能。
您需要以下内容:
...
Node earlierNode = rootNode;
for (int j = 0; j < i; j++) {
if (earlierNode.getInfo().equals(node.getInfo())) {
isDistinct = false;
}
earlierNode = earlierNode.getNext();
}
...
答案 3 :(得分:0)
使用套装
Set<Node> mySet = new HashSet<Node>(list);
answer = mySet.size();
这取决于您在节点类中实现hashCode和equals,或者您可以使用TreeSet和Comparator。
Comparator<Node> myComparator = new MyCustomComparator();// you have to define your comparator.
Set<Node> mySet = new TreeSet<Node>(myComparator);
mySet.addAll(list);
answer = mySet.size();
答案 4 :(得分:0)
第一次围绕i
循环,j
循环不执行任何操作(因为它从0开始并在j < i
继续而不是),因此您离开{{1}设置为true而不用任何东西进行比较。
尝试从1开始distinct
。