使用递归将数组转换为自定义LinkedList类

时间:2010-11-02 02:22:21

标签: java recursion linked-list

我正在使用类似这样的自定义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 WITHOUT循环,因此使用递归。如何在没有循环的情况下完成?这对我来说是不可想象的。我从哪里开始?

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

8 个答案:

答案 0 :(得分:2)

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;
}

答案 1 :(得分:1)

我不确定您使用的语言是什么,但这是一个大致的想法:

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[]));
}

你必须用你正在使用的任何语言进行子串和边界检查。

答案 2 :(得分:1)

怎么样:

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;
    }
}

要添加,也可能值得指出,使用递归创建集合在实践中非常糟糕 - 它可以轻松地消除堆栈大小。

答案 3 :(得分:1)

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

    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);

答案 4 :(得分:1)

首先,你可以用迭代(循环)做任何你可以做的递归,反之亦然(虽然没有尾部调用消除,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(第一个元素)和它后面的每个元素。

现在编写“帮助”方法,这是完成所有实际工作的地方。

首先,让基础案例不受影响。基本情况是我们转换的数组部分为空。如果offset >= a.length那就是这种情况。在这种情况下,我们想要返回一个空LinkedList,实际上由null表示。那么return null就是这样。

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

答案 5 :(得分:0)

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

这会让你头疼吗?你能从那里弄清楚吗?

答案 6 :(得分:0)

试试这个:

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);

}

答案 7 :(得分:0)

好的,因为需要使用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));
}