【问题标题】:How to recursively concatenate a list of string elements如何递归连接字符串元素列表
【发布时间】:2011-10-07 16:51:21
【问题描述】:

我正在查看准备考试的示例,坦率地说,我不太擅长递归或列表,尤其是列表。

给定一个节点类,它将保存字符串(不是通用的)编写一个名为 concat 的递归 java 函数,该函数接受一个表示链表头部的节点并返回一个表示链表所有元素连接的字符串,如果列表为空,字符串也应为空。

任何帮助将不胜感激。

(以下是我提问前输入的内容:)

public static String FindConcat(Node head) {
    String s = "";
    if(head == null) return s;
    else if(head.next = null) {
        s += head.data;
        return s;
    }
    else {

    }

}

感谢您的回复。

【问题讨论】:

  • 递归方法在方法结束时调用自身,需要有一个检查,当某些情况发生时退出方法。发布的任何不调用自身的答案都不是递归方法。
  • 这些说明专门要求提供一个递归函数,以测试您对递归的了解。后来,在现实生活中,任意数量的字符串可能会与 StringBuilder 连接,并且迭代将优于递归。如果您觉得这样的事情很有趣,您可以考虑如何将 StringBuilder 与递归方法一起使用。
  • else if(head.next = null) { 我认为这行不通,它应该读为==!=,这取决于你想做什么。

标签: java


【解决方案1】:

在这种情况下,什么递归是找到基本情况以及如何将数据“划分”到这个基本情况。所以首先定义你的“基本情况”。

  • 基本情况:函数的参数为​​空
  • 在获得基本情况之前,追加节点的文本并跳过第一个元素

这是你的方法:

public static String FindConcat(Node head) {
    if (head == null) 
        return ""; // base case

    // devide it down (run recursive FindConcat on the _next_ node)
    return head.data + FindConcat(head.next);
}

这个简单的例子将打印hello this is a linked list:

public class Test {
    // this is a very basic Node class
    static class Node {
        String text;
        Node next;

        public Node(String text) {
            this.text = text;
        }
        // used for building the list
        public Node add(String text) {
            next = new Node(text);
            return next;
        }
    }

    // this is the recursive method concat
    public static String concat(Node node) {
        if (node == null)
            return "";

        return node.text + " " + concat(node.next);
    }

    public static void main(String[] args) {
        // build the list
        Node head = new Node("hello");
        head.add("this").add("is").add("a").add("linked").add("list");

        // print the result of concat
        System.out.println(concat(head));
    }
}

【讨论】:

    【解决方案2】:

    如果您的节点为空,则返回一个空字符串。

    否则,获取字符串,进行递归调用(以获取其余节点的连接结果),并将其附加到字符串并返回结果。

    【讨论】:

      【解决方案3】:

      因为这听起来像是家庭作业,所以我会提出一个建议。

      首先编写在列表只有一个元素(即没有下一个节点)时有效的方法。将其用作递归调用的基础。

      【讨论】:

      • 这不是作业,只是学习指南。我有一个 null 的条件,也许是不必要的,否则只有一个元素。看起来其他一些人也给了我一些很好的反馈。谢谢。
      【解决方案4】:

      链接列表的递归遍历通常看起来像查看您是否在列表的末尾(您得到的引用是null),如果不是,则在下一个递归调用中做一些事情列表的元素,如果你是,做基本情况的事情。假设节点从外部看起来像这样:

      public class Node{
          public Node getNext();
          public String toString();
      }
      

      ...你的方法看起来像这样(在你用来运行它的类中):

      public String concatList(Node head){
          if(head == null){
              return ""; //empty list is a null pointer: return empty string
          }
          return head.toString() + concatList(head.getNext());
      }
      

      列表的结尾,或者根本没有列表,看起来一样——一个空指针——并返回指定的空白字符串;其他所有内容都采用当前节点并将其连接到通过获取字符串的整个其余部分的连接版本创建的列表。

      小心:如果某些东西损坏了你的列表,所以它实际上是一个循环,它不会对此进行检查,并且会一直运行,直到堆栈内存用完,除非 Java 正确检测到这个递归函数的循环优化并且它只会简单地永远运行。

      【讨论】:

        【解决方案5】:

        这是一个非常完整的例子:

        import java.util.Arrays;
        import java.util.List;
        import java.util.UUID;
        
        public class RecurisveLinkedListExample
        {
            public static String concat(final Node node)
            {
                if (node == null)
                {
                    return "";
                }
                else
                {
                    return node.getData() + concat(node.getNext());
                }
            }
        
            public static void main(String[] args)
            {
                final List<String> input = Arrays.asList("A", "B", "C", "D");
                final Node head = new Node(null, input.get(0));
                Node previous = head;
                for (int i = 1; i < input.size(); i++)
                {
                    previous = previous.addNext(input.get(i));
                }
        
                System.out.println(concat(head));
            }
        
            public static class Node
            {
                private final UUID id;
                private final Node previous;
                private final String data;
                private Node next;
        
                public Node(final Node previous, final String data)
                {
                    this.previous = previous;
                    this.data = data;
                    this.next = null;
                    this.id = UUID.randomUUID();
                }
        
                public Node getPrevious()
                {
                    return previous;
                }
        
                public String getData()
                {
                    return data;
                }
        
                public Node addNext(final String data)
                {
                    this.next = new Node(this, data);
                    return this.next;
                }
        
                public Node getNext()
                {
                    return next;
                }
        
                @Override
                public String toString()
                {
                    return String.format("%s:%s:%s", 
                           this.previous == null ? "HEAD" : this.previous.id, 
                           this.data, 
                           this.next == null ? "TAIL" : this.next.id);
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-28
          • 1970-01-01
          • 1970-01-01
          • 2021-10-05
          • 2021-10-21
          • 1970-01-01
          • 1970-01-01
          • 2019-10-22
          相关资源
          最近更新 更多