Java中的递归和链表

发布于 2024-09-30 07:47:17 字数 675 浏览 4 评论 0原文

好吧,假设我有一个在自定义 LinkedList 类中查找特定单词的函数:

public LinkedList find(String word) {
    if (this.word.equals(word))
        return this;
    if (next==null)
        return null;
    if (next.find(word)==next)
        return next;
    return null;
}

此代码工作正常,但它返回第一个找到的与条件匹配的对象。如果我想返回找到的与参数匹配的最后一个对象怎么办?我很难弄清楚这一点。请记住我想使用递归。

编辑:这段代码有什么问题:

public LinkedList findLast(String word) {
    LinkedList temp=new LinkedList(word, null);
    if (next==null && next.word.equals(word))
        return next;
    if (next==null && !next.word.equals(word))
        temp=next.findLast(word);
    return temp;
}

Ok so say I have a function that looks for a specific word in a custom LinkedList class:

public LinkedList find(String word) {
    if (this.word.equals(word))
        return this;
    if (next==null)
        return null;
    if (next.find(word)==next)
        return next;
    return null;
}

This code works fine, however it returns the FIRST found object that matches the criteria. What if I wanted to return the LAST object found that matches the paramater? I'm having a hard time figuring this out. Keep in mind I want to use recursion.

EDIT: What would be wrong with this code:

public LinkedList findLast(String word) {
    LinkedList temp=new LinkedList(word, null);
    if (next==null && next.word.equals(word))
        return next;
    if (next==null && !next.word.equals(word))
        temp=next.findLast(word);
    return temp;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

心欲静而疯不止 2024-10-07 07:47:17

好吧,这样想:您需要向右递归到列表的末尾,然后让返回值向上冒泡。

因此,您的方法的开头应该是递归调用以进一步查看列表,或者注意到我们位于列表的末尾 - 这相当于“进一步”结果为空。

现在,当您返回时,有三个选项:

  • 您已经找到晚于当前点的匹配项 - 因此返回该引用
  • 找到匹配项(因此返回值递归调用为空)并且:
    • 当前点的单词匹配 - 因此返回当前点
    • 当前点不匹配 - 因此返回 null

希望这足以让您实现 - 如果没有,请提出更多问题。当这可能是家庭作业时,我宁愿不给出完整的实现。

Well, think of it this way: you need to recurse right to the end of the list, and then let the return value bubble up.

So the start of your method should either be a recursive call to look further down the list, or noting that we're at the end of the list - which is equivalent to the "further" result being null.

Now when you're returning, there are three options:

  • You've already found a match later than the current point - so return that reference
  • You've not found a match (so the return value of the recursive call was null) and:
    • The current point's word matches - so return the current point
    • The current point doesn't match - so return null

Hopefully that should be enough to get you to an implementation - if not, please ask more questions. I'd rather not give a full implementation when this is presumably homework.

惜醉颜 2024-10-07 07:47:17

存储对找到的最新引用的引用,并继续调用自身,直到返回 null——然后返回最新引用。

请注意,为了澄清:您将必须迭代整个链接列表(除非您有双向链接列表)才能实现此目的 - 每次找到匹配项时都存储一个引用(但只需覆盖相同的引用)每次引用)——然后一旦到达此列表的末尾,就返回引用所保存的任何内容。

public class LinkedList {

  private static int uniqueIdCounter = 0;

  private final String word;
  private int uniqueId;
  private LinkedList next = null;

  public LinkedList( String word ) {

    this.word = word;
    this.uniqueId = uniqueIdCounter++;
  }

  @Override
  public String toString() {

    return this.word + "(" + this.uniqueId + ")";
  }



  public void setNext( LinkedList next ) {

    this.next = next;
  }

  public LinkedList find( String word ) {

    return this.find( word, null );
  }

  public LinkedList find( String word, LinkedList result ) {

    if( this.word.equals( word ) ) {
        result = this;
    }

    if( this.next != null ) {

        result = this.next.find(word, result);
    }

    return result;
  }

  public static void main(String[] args) {

    LinkedList head = new LinkedList( "A");
    System.out.println( "Head is: " + head );

    LinkedList B = new LinkedList( "B" );
    head.setNext( B );
    System.out.println( "B is: " + B );

    LinkedList A2 = new LinkedList( "A" );
    B.setNext( A2 );
    System.out.println( "A2 is: " + A2 );

    LinkedList last = head.find( "A" );
    System.out.println( "Last is: " + last );
  }

}

这是输出:

头是:A(0)

B 为:B(1)

A2 是:A(2)

最后是:A(2)

Store a reference to the latest one found and keep on calling itself until it returns null -- then return the latest-reference.

Note, for clarification: you're going to have to iterate through your entire linked-list (unless you have a doubly-linked-list) to achieve this -- store a reference every time you find a match (but just overwrite the same reference each time) -- then return whatever the reference holds once you reach the end of this list.

public class LinkedList {

  private static int uniqueIdCounter = 0;

  private final String word;
  private int uniqueId;
  private LinkedList next = null;

  public LinkedList( String word ) {

    this.word = word;
    this.uniqueId = uniqueIdCounter++;
  }

  @Override
  public String toString() {

    return this.word + "(" + this.uniqueId + ")";
  }



  public void setNext( LinkedList next ) {

    this.next = next;
  }

  public LinkedList find( String word ) {

    return this.find( word, null );
  }

  public LinkedList find( String word, LinkedList result ) {

    if( this.word.equals( word ) ) {
        result = this;
    }

    if( this.next != null ) {

        result = this.next.find(word, result);
    }

    return result;
  }

  public static void main(String[] args) {

    LinkedList head = new LinkedList( "A");
    System.out.println( "Head is: " + head );

    LinkedList B = new LinkedList( "B" );
    head.setNext( B );
    System.out.println( "B is: " + B );

    LinkedList A2 = new LinkedList( "A" );
    B.setNext( A2 );
    System.out.println( "A2 is: " + A2 );

    LinkedList last = head.find( "A" );
    System.out.println( "Last is: " + last );
  }

}

And here's the output:

Head is: A(0)

B is: B(1)

A2 is: A(2)

Last is: A(2)

就像说晚安 2024-10-07 07:47:17

每个直接递归函数都有两个地方可以执行一些有用的操作:在进一步的方法调用之前和之后:

  function(n){
    doBefore(n);
    function(n+1)
    doAfter(n)
  }

doBefore() 在“前进的路上”执行,doAfter() 在“返回的路上”执行。现在,您的算法会在前进过程中检查单词相等性。您必须修改您的算法,以便在返回时执行此检查。

Every straight recursive function has two places for some useful actions: before further method call and after:

  function(n){
    doBefore(n);
    function(n+1)
    doAfter(n)
  }

doBefore() is executed "on the way forward", doAfter() is executed "on the way back". Now your algorithm checks word equality on the way forward. You have to modify your algorithm so that this check is performed on the way back.

一绘本一梦想 2024-10-07 07:47:17
public LinkedList find(String word, LinkedList result) {
   if (this.word.equals(word))
        result = this;
   if (next != null )
        return next.find(word, result)
   return result;

两句:

public LinkedList find(String word, LinkedList result) {
     result = this.word.equals(word) ? this : result;
     return next == null ? result : next.find(word, result);

@fprime:是的,解释:记住结果,用后面的结果替换它,最后返回。

只有一个参数的方法:

public LinkedList find(String word){
   result = this.word.equals(word) ? this : null;
   if(next != null)
      previous = next.find(word);
      return (previous != null) ? previous : result 
   else 
      return result;
public LinkedList find(String word, LinkedList result) {
   if (this.word.equals(word))
        result = this;
   if (next != null )
        return next.find(word, result)
   return result;

Two-liner:

public LinkedList find(String word, LinkedList result) {
     result = this.word.equals(word) ? this : result;
     return next == null ? result : next.find(word, result);

@fprime: Ya, explanation: remember the result, replace it with later result, return when at the end.

Method with one argument:

public LinkedList find(String word){
   result = this.word.equals(word) ? this : null;
   if(next != null)
      previous = next.find(word);
      return (previous != null) ? previous : result 
   else 
      return result;
琴流音 2024-10-07 07:47:17

只要从尾部向后跑就可以了。

public LinkedList find(String word) {
        if (this.word.equals(word))
            return this;
        if (prev==null)
            return null;
        if (prev.find(word)==prev)
            return prev;
        return null;
}

Just run it backwards from the tail.

public LinkedList find(String word) {
        if (this.word.equals(word))
            return this;
        if (prev==null)
            return null;
        if (prev.find(word)==prev)
            return prev;
        return null;
}
陌生 2024-10-07 07:47:17

首先,您最初的 find(String word) 无法正常工作。

你的第一个 if 语句是完美的。这是您成功的基本案例。

你的第二个 if 语句也很完美。这是你失败的基本情况。

第三个是你出轨的地方。您已经处理了所有(在本例中是两个)基本情况,现在剩下的就是递归情况。您无需在这里检查任何内容。 next.find(word) 将返回正确答案,无论成功还是失败。

对于 findLast(String word),我无法对 Jon Skeet 所说的内容添加太多内容。关于我可以添加的唯一建议是永远不要让节点检查其邻居。每个节点应该只检查自己。您应该会看到大量 this.word.equals(word),但不会看到 next.word.equals(word)

To start with, you initial find(String word) does not work correctly.

Your first if statement is perfect. It is you success base case.

Your second if statement is also perfect. It is your failure base case.

Your third is where you go off the rails. You have handled all (in this case both) base cases, now all that is left is the recursive case. You don't need to check anything here. next.find(word) will return the correct answer, success or fail.

For findLast(String word), I can't add much to what Jon Skeet said. About the only advice I can add it to never have the a node check its neighbor. Each node should only ever check itself. You should see plenty of this.word.equals(word) but never next.word.equals(word).

筱果果 2024-10-07 07:47:17
public LinkedList find(String word) {
  if(this.word.equals(word)) return this;
  return next==null?null:next.find(word);
}

公共LinkedList rfind(字符串字){ 如果(下一个!=空){ LinkedList res = next.rfind(word); if(res != null) 返回 res; } return this.word.equals(word)?this:null; }


public LinkedList find(String word) {
if(this.word.equals(word)) return this;
return next==null?null:next.find(word);
}

public LinkedList rfind(String word) {
if(next != null) {
LinkedList res = next.rfind(word);
if(res != null) return res;
}
return this.word.equals(word)?this:null;
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文