繁体   English   中英

通过递归将数组转换为自定义LinkedList类

[英]Converting an array to a custom LinkedList class with recursion

我正在使用这样的自定义LinkedList类:

public class LinkedList {
    // Get and Set methods are NOT necessary!

    private LinkedList next;    
    private final String word;

    public LinkedList(String word, LinkedList next) {
        this.word = word;
        this.next = next;
    }

现在,我的任务是编写一个方法,该方法采用一个字符串数组,并将每个字符串对象转换为一个不带循环的LinkedList,因此使用递归。 如何做到没有循环? 这对我来说是不可想象的。 我从哪开始呢?

编辑:让我澄清一下,我应该编写的函数只接受一个参数(它是字符串数组),并返回LinkedList。

enter code here
    public LinkedList arrayToLinkedList(String[] myArray)
{
        String[] toConvert = myArray;
        List<String> toConvertList = (List) Arrays.asList(toConvert);
        LinkedList<String> convertedLinkedList = new LinkedList<String>(toConvertList); 
        return convertedLinkedList;
}

我不确定您使用的是哪种语言,但这是一个基本思路:

public LinkedList myfunction(String arr[]) {
    if(arr.empty == true)
        return void;

    //return the array minus the first element
    String shorterarray[] = substr(arr[],1);

    //recursively create the next element
    LinkedList myItem = new LinkedList(arr[0], myfunction(shorterarray[]));
}

您将必须使用所使用的任何语言来进行字幕和边界检查。

怎么样:

public static void main(String[] args) {
    String[] data = new String[] { "1", "2", "3" };

    LinkedList head = build(data);
    while (head != null) {
        System.out.println(head.word);
        head = head.next;
    }
}

private static LinkedList build(String[] data) {
    if (data == null || data.length == 0) {
        return null;
    }

    LinkedList head = new LinkedList(data[0], null);
    build(head, data, 1);
    return head;
}

private static LinkedList build(LinkedList node, String[] data, int index) {
    if (index == data.length) {
        return node;
    }

    node.next = build(new LinkedList(data[index], null), data, ++index);
    return node;
}

private static class LinkedList {
    private final String word;
    private LinkedList next;    

    public LinkedList(String word, LinkedList next) {
        this.word = word;
        this.next = next;
    }
}

补充一点,也许值得指出的是,在实践中使用递归创建集合确实不好,因为它很容易耗尽堆栈大小。

可能只有我一个,但我不喜欢提供的任何解决方案。

    public static LinkedList Of(String[] input) {
        if (input == null || input.length < 1)
            return null;
        return LinkedList.Of(input, input.length - 1);
    }

    public static LinkedList Of(String[] input, int i) {
        if (i > 0)
            return new LinkedList(input[i], LinkedList.Of(input, i - 1));
        return new LinkedList(input[i], null);
    }

否决票令人恐惧,所以这里的顺序正确:

    /**
     * Creates linked list from array input.
     * 
     * @param input
     *            data array
     * @return linked list with data
     */
    public static LinkedList Of(String[] input) {
        // Checks if array has elements.
        if (input == null || input.length < 1)
            return null;
        // Starts creating the array using overload 2.
        return LinkedList.Of(input, 0);
    }

    /**
     * Creates linked list from array input (overload 2).
     * 
     * @param input
     *            data array
     * @param i
     *            counter to remember at what element is current
     * @return linked list with data
     */
    public static LinkedList Of(String[] input, int i) {
        //Tests if counter is within array elements. 
        if (input.length - 1 > i)
            // Returns new element with (current element data, reference
            // to next element). Note that next element will be returned
            // by this same method (this is why it is recursive).
            return new LinkedList(input[i], LinkedList.Of(input, i + 1));
        //Last element. From here backtracking will begin. 
        return new LinkedList(input[i], null);
    }

这里有一些表决:

    public String toString() {
        StringBuilder sb = new StringBuilder(this.word);
        LinkedList tmp = this;
        while (tmp.next != null) {
            sb.append(" > ");
            tmp = tmp.next;
            if (tmp.word != null)
                sb.append(tmp.word);
        }
        return sb.toString();
    }

并测试:

    String str = "Neque porro quisquam est qui dolorem ipsum quia "
            + "dolor sit amet, consectetur, adipisci velit...";
    LinkedList ll = LinkedList.Of(str.split("\\s+"));
    System.out.println(ll);

首先,您可以使用迭代(循环)执行任何操作,也可以使用递归进行操作,反之亦然(尽管没有尾部消除,Java却没有,但递归通常比迭代要昂贵)。

当试图找出如何递归解决问题时,您想弄清楚如何分解一个或多个看起来像同类问题,但规模较小的问题。 对于列表问题,这通常意味着给定n个元素列表时,您要递归处理n -1个元素。 您还需要有一个基本情况,以便递归将终止。 带列表的基本情况通常是0个元素的列表。

数组很像一个列表,但是Java数组没有切片(即:您不能只传递一个数组的一部分),因此您需要一个帮助器方法来知道我们关心的是数组的哪一部分关于:

private static LinkedList fromArray(String[] a, int offset) {

由于您的LinkedList类分解为一个单词,然后分解为列表的尾部(由next指向),因此对我们来说,也应处理输入数组的尾部。 offset参数让我们知道我们将要看数组尾部的多少:这是我们关心的第一个索引。

public方法将仅调用helper方法,并将其偏移量设置为0:

public static LinkedList fromArray(String[] a) {
    return fromArray(a, 0);
}

偏移量0表示我们关心元素0(第一个元素)及其后的每个元素。

因此,现在编写“ helper”方法,完成所有实际工作。

首先,将基本情况排除在外。 基本情况是我们要转换的数组部分为空。 如果offset >= a.length就是这种情况。 在这种情况下,我们想返回一个空的LinkedList ,它实际上由null表示。 因此,在这种情况下,请return null

处理完基本情况后,请考虑递归情况。 我们关心的数组部分中有一个或多个元素。 让我们创建一个LinkedList来保存第一个元素a[offset] (我们关心的第一个元素是。回想一下,帮助器仅关心从offset开始到结尾的数组部分。)其余元素可以通过调用自己传入同一数组来处理,但是将offset增加1,因为我们不希望递归调用处理已经处理过的元素。

调用一个带有三个参数的函数; 源数组,数组中的当前位置以及目标链接列表。

那会让你动脑子吗?你能从那里弄清楚吗?

尝试这个:

private LinkedList formlist(LinkedList list, String[] str, int length, int i) {
    if(i==length)
        return list;
    return formlist(new LinkedList (str[i],list),str,length,i+1);

}

好的,因为需要使用String [] args的单个方法。 这是一个Java示例。 (基于先前的答案,但转换为java)

private LinkedList build(String arr[]) {
    if(arr.length == 0)
        return null;

    //return the array minus the first element
    String shorterarray[] = Arrays.copyOfRange(arr, 1, arr.length);

    //recursively create the next element
    return new LinkedList(arr[0], build(shorterarray));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM