简单的 Java 列表问题

Simple Java List Question

提问人:Jeff 提问时间:10/26/2009 最后编辑:IAdapterJeff 更新时间:10/26/2009 访问量:1728

问:

我应该创建一个迭代方法拉伸,该方法将正数 n 作为参数,并返回一个新的 ListItem 开始一个列表,其中原始列表中的每个数字都重复了 n 次。例如,如果原始列表为 ( 6 7 6 9 ),参数值为 2,则返回的新列表为 ( 6 6 7 7 6 6 9 )。

我已经有一个列表项构造函数,该构造函数具有该节点的值和对下一个节点的引用:

   ListItem(int number, ListItem next) {
        this.number = number;
        this.next   = next;
}

我的代码如下所示:

    public ListItem stretch(int n) {
        //make an array of list items that is n times bigger than the original one.
        ListItem[] newList = new ListItem[this.length() * n];

    //Then loop through the old list one value at a time. At each value do a second loop n times to stretch

        int index = 0;
        int counter = 0;
        for(int i = 0; i < this.length(); i++){
            while(counter++ < n){
                newList[index++] = this[i];*************************
        }
        return newList;****************
    }

}

有两个问题点,我把它们放在了星号上。我应该返回一个列表项,但 NewList 是一个数组。 我不确定第一个星号行有什么问题。

任何帮助/指导将不胜感激。

Java 算法 列表

评论

0赞 San Jacinto 10/26/2009
这是什么类型?不知道为什么要给它下标。
1赞 theycallmemorty 10/26/2009
圣哈辛托的意思是这个[i];部分几乎可以肯定是错误的。

答:

2赞 theycallmemorty 10/26/2009 #1

作业?

看起来你应该构建一个链表,但你正在构建一个 ListItems 数组。ListItems 数组还不错,但需要使每个 ListItem 的下一个值指向列表中的下一项。

然后,函数的最后一行将返回列表中的第一项。

评论

0赞 Jeff 10/26/2009
对不起,我是 java 的新手。你能更详细地介绍一下吗?我不希望你写代码,因为那样我就无法学习,但有关该主题的更多细节可能会有所帮助。谢谢。
0赞 theycallmemorty 10/26/2009
如果你有一个 ListItem,第二个是 ListItem,那么你需要做一些类似 first.next = second 的事情;使第一个 ListItem “知道”它后面的 ListItem。
0赞 ankon 10/26/2009 #2

第一个星号行肯定是错误的,但如果你仔细想想,这不是你的问题:你一开始就没有被要求返回一个数组。

如果你考虑一下你的输入到底是什么样子,那么关于如何返回 ListItem 的问题应该会自行解决:拿一张纸,画出来,你就会明白为什么返回一个列表项就足够了,以及在 ListItem 上做什么才能使每个项目加倍。

0赞 SLaks 10/26/2009 #3

第一行的问题在于,由于不是数组,因此不能为其下标()。如果没有关于你的班级的更多细节,我无法帮助你解决这个问题。你在做一个链表吗?this[i]ListItem

对于返回值,您可能希望返回数组中的第一项。如果是这样,请将其更改为 。如果要返回数组,请更改函数以返回数组,如下所示: .return newList[0]public ListItem[] stretch(

3赞 bendin 10/26/2009 #4

解决这个问题的最好方法是画一些图画。然后尝试将问题分解为子问题。让我们从一个简单的案例开始:长度为 2 的列表:

ListItem two = new ListItem(1, ListItem(2, null));

这是一张图片

two = ( number == 1
      ( next   == ( number == 2
                  ( next   == null

这是另一张图片:

+---+  +---+    The "/" here is the "null" above, which terminates the list.
| 1 |->| 2 |-/  
+---+  +---+    

可以这样想:列表由第一个 ListItem 组成,它通过“next”指向列表的其余部分。空列表为 null,最后一个 ListItem 的“next”始终为空。(空)。

现在,当我们被要求“延伸”一个列表时,到底发生了什么?比如说,2?

好吧,空列表很容易,它不会改变。但它也无关紧要,因为在您使用的语言中会以糟糕的方式结束。长度 1 的列表是我们最简单的实际情况:null.stretch()

我们有:

we have       we want

+---+         +---+   +---+
| 1 |-/       | 1 |-->| 1 |-/
+----         +---+   +---+

好吧,这并不难。我们已经有一个长度为一的列表。我们需要做的就是将它挂在新 ListItem 的下一个位置,我们将得到一个长度为 2 的列表。显然,我们需要能够将某些内容添加到现有列表中。将它添加到前面是最简单的,因此我们将为此定义一个小助手:

ListItem addItemToFront(int number) {
    return new ListItem(number, this);
} 

好了,现在让我们把它编码起来,把它命名为 stretchFirstItemByOne:

ListItem stretchFirstItemByOne() {           
    return this.addItemToFront(this.number); 
}

你会看到我在这些例子中经常使用 this.something(), 虽然没有必要。我只是想澄清这一点 这些是对当前对象 (this) 的方法调用。

但是,假设我们想伸展一些更大的 n?你已经尝试过 - 有点不幸 - 使用上面的for循环。你可以这样做。但我会以不同的方式去做。

ListItem stretchFirstItem(n) {
    if (n == 1)      // stretching to length 1 means nothing
        return this; // to do. just return this.
    else {
        // well, if we stretch our item to length n-1 first
        // then all we have to do is stretch it by one and
        // we're done.
        return this.stretchFirstItem(n-1).stretchFirstItemByOne(); 
    }
}

停下来想一想那个。如果遇到问题,请将其重写为 for 循环。

你可能会说,这一切都很好,但它只处理长度为 1 的列表。多么真实,多么真实。

假设您有一个长度为 3 的列表,并且您想将其拉长 2。

  +---+  +---+  +---+
( | 1 |->| 2 |->| 3 |-/ ).stretch(2)
  +---+  +---+  +---+

艰难?好吧,我们至少可以开始了。如果列表只有一个项目,我们知道如何处理事情:

ListItem stretch(int n) {
    ListItem restOfList = this.next;
    if (restOfList == null) { // this list has length one
        return this.stretchFirstItem(n);
    } else {
        // if we had the rest of the list stretched, then we could
        // add this.number to the front of this stretched list, stretch
        // that first item and then we'd be done.
    }
}

嘿,但是 stretch 不应该为我们做这件事吗,你知道,拉伸整个列表吗?我们不能用它来拉伸列表的其余部分,这样我们就可以做简单的部分并拉伸第一项吗?但是我们甚至还没有写完伸展 -- 我的意思是-- 它不起作用。这不可能那么容易,不是吗?可以吗?

ListItem stretch(int n) {
    ListItem restOfList = this.next;
    if (restOfList == null) { // this list has length one
        return this.stretchFirstItem(n);
    } else {
        return restOfList     //-------------------------
           .magic(...)        // Left as an exercise for
           .moreMagic(...)    // the reader.
           .zyzzy(...);       //-------------------------
    }
}