【问题标题】:Listnode problem implementing the count occurrences method (recursive)实现计数出现方法的Listnode问题(递归)
【发布时间】:2020-03-29 14:17:45
【问题描述】:

大家好,我正在尝试实现 ListNode,但我对这两种方法都有问题

  • contains(E data) 接受一个通用对象并检查其是否存在于列表中。

  • countIf(E data)接受一个通用对象并检查它在 ListNode 中的出现。

我知道它可以以迭代的方式实现,但我想练习递归,所以请告诉我我做错了什么:

public class ListNode2<E> {

    public E data;

    public ListNode2<E> next;

    public ListNode2(){
        this.data=null;
        this.next=null;
    }
    public ListNode2(E data, ListNode2<E> n) {
        this.data = data;
        next= n;
    }

    public ListNode2(E data) {
        this.data = data;
        next=null;
    }

    public E getData() {
        return this.data;
    }

    public ListNode2<E> getNext() {
        return this.next;
    }

    public ListNode2<E> addFirst(E data) {
        return new ListNode2<>(data, this);
    }
    public boolean contains(E data){

        if ( data ==null && this.getData()==null )
            return true;

        if (data!=null && (data.equals(this.getData())))
            return true;

        if (this.next==null)//remove the next and we have nullpointer exception but right results :( 
            return false;

        return this.getNext().contains(data);
    }    

    public int countIf(E data) {
        //i was missing the getNext() but now i get for the first element zero
        if(this.getNext()==null)
            return 0;

        if (data ==null && this.getData() == null )
            return 1+ getNext().countIf(data);

        if ( data!= null && (data.equals(this.getData())) )
            return 1 + getNext().countIf(data);



        return getNext().countIf(data);
    }

    public int size() {
        if (getNext() == null) {
            return 1;
        } else {
            return 1 + getNext().size();
        }
    }

    @Override
    public String toString() {
        return data + " ";
    }

    public static void main(String[] args) {

        ListNode2<Integer> list = null; // Leere Liste.
        list = new ListNode2<Integer>(1); // ergibt 1.
        list = list.addFirst(2);
        list = list.addFirst(3);
        list = list.addFirst(4);
        int size = list.size();

        System.out.println(size);

        System.out.println("countif 1 "+ list.countIf(1));//this gives 0 why??
        System.out.println("countif 2 "+ list.countIf(2));
        System.out.println("countif 3 "+ list.countIf(3));
        System.out.println("countif 5 "+ list.countIf(5));
        System.out.println("countif null "+ list.countIf(null));
        System.out.println("countif 7 "+ list.countIf(7));
    }
}

我在 countIf 方法中做错了什么?我好像搞不懂?

编辑: 更正了用户建议的包含方法:Ole V.V.。 但在 countIF() 上应用相同的提示:它看起来像这样

    public int countIf(E data) {

    if (data!= null && (data.equals(this.getData())) )
        return 1 + getNext().countIf(data);//this line is the 74

    if ( data ==null && this.getData() == null )
        return 1+ getNext().countIf(data);

    if(this.getNext()==null)
        return 0;


    return getNext().countIf(data);   //this line is the 83 
}

输出:

    Exception in thread "main" java.lang.NullPointerException
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:74)
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:83)
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:83)
    at de.hsmannheim.inf.pr2.ads.ListNode2.countIf(ListNode2.java:83)
    at de.hsmannheim.inf.pr2.ads.ListNode2.main(ListNode2.java:126)
/home/pi/.cache/netbeans/11.0/executor-snippets/run.xml:111: The following error occurred while executing this line:
/home/pi/.cache/netbeans/11.0/executor-snippets/run.xml:68: Java returned: 1
BUILD FAILED (total time: 0 seconds)

【问题讨论】:

    标签: java recursion linked-list implementation


    【解决方案1】:

    这与您执行检查的顺序有关。

        public boolean contains(E data){
    
            if (this.next==null)//remove the next and we have nullpointer exception but right results :( add the 
                return false;
    
            if ( data ==null && this.getData()==null )
                return true;
    
            if (data!=null && (data.equals(this.getData())))
                return true;
    
            return this.getNext().contains(data);
        }    
    

    现在如果寻找的数据元素在最后一个节点中,会发生什么?首先检查next 是否为null。它是。所以你返回false。您永远不会发现数据在同一个节点中是正确的。

    相反,您需要将 null 检查放在对内容的两次检查之后(当然,仍然在包含递归调用的 return 语句之前)。

    编辑:countIf() 的情况类似但更复杂。同样,您首先需要测试数据是否是搜索的数据,如果是则“计数”它,获得 0 或 1。然后测试 nextgetNext() 是否为 null。如果是,则返回获得的计数。最后你需要将之前获得的计数添加到递归调用的结果中。

    顺便说一句,代码不错。

    【讨论】:

    • 我知道countIf() 方法中出现问题的原因是什么,但我的第一个元素仍然为零,就好像它不存在一样
    • 我在这里追逐一个移动的目标,因为您的问题有很多编辑。我不知道要回答哪个版本,也不知道您是否会进行可能使我的回答无效的进一步编辑。我仍然相信我的回答在某些时候是中肯的,同样是关于countIf()。如果您已经编辑了该方法,但仍然不明白为什么它会给出不正确的结果,请提出一个新问题。你可以从这里链接到你的新问题,然后如果我有很好的检查机会,我会的。
    • 先生,在 countif() 方法中,我只是更改了第一个 if 子句,它是 this==null 并且我使它成为 this.getNext()==null 什么都没有。我什至没有改变 if 子句的位置。
    • 我可以发布另一个问题,但我不喜欢在堆栈溢出中发送垃圾邮件,如果我问了同一主题的 2 个问题,这对于像你这样愿意提供帮助的好人来说并不是很好。但是,如果有任何方法可以让我从另一篇文章中标记你,那么我会删除这个并发布另一个然后如果没有人回答我会标记你:)
    • 在您的 countIf 方法中,您仍然有一个类似于您从一开始就在 contains 中的顺序的检查顺序。该命令在contains 中给您带来了问题。它仍然给你countIf 中的问题。请相信自己。您可以通过类似于您在contains() 中解决它的方式来解决它。
    【解决方案2】:

    您的countIf 函数没有考虑第一个元素的值。 您可以通过以下方式更正它:

    public int countIf(E data)
    {
      boolean isDataEq = Objects.equals(data, this.data);
    
      if(getNext() == null)
      {
        return isDataEq ? 1 : 0;
      }
    
      int nextCount = getNext().countIf(data);
      return isDataEq ? 1 + nextCount : nextCount;
    }
    

    您可以通过以下方式简化您的contains 函数:

    public boolean contains(E data)
    {
      if (Objects.equals(data, this.data)) return true;
      if (next==null) return false;
      return next.contains(data);
    }
    

    【讨论】:

    • 感谢先生提出这个伟大的解决方案,但我想知道如何修复我的代码而不用你的代码替换它,因为我是一名 cs 学生,我在业余时间进行编码以获得更好的。所以知道其他方法以及知道如何纠正我的错误对我来说很有趣。所以你知道如何调整我的代码以完美地像你的那样工作,因为我无法弄清楚吗?提前致谢。
    • 你的问题是if(this.getNext()==null) return 0;,正如我所说的。你应该像这样纠正它if(this.getNext()==null) return Objects.equals(data, this.data) ? 1 : 0;
    • 如果你知道两个比较参数都可以为空,我建议你使用Objects.equals。它会让你更简洁。
    • 天哪,现在我明白了。所以我们添加检查是否到达最后一个元素,并且最后一个元素和最后一个元素相同,我们返回 1 而不是 0,这太棒了!但我想打自己的脸哈哈哈……我怎么没弄明白……非常感谢。
    • 实际上我不知道 Object.equals 这样的东西,直到您在解决方案中提交它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 2020-06-01
    • 1970-01-01
    相关资源
    最近更新 更多