如何添加到链表的数组列表中



如果这是一个愚蠢的问题,我很抱歉,但我是Java链表和数组列表的新手。

我想做的是:我有一个文本文件,我逐字逐句地浏览。我想创建一个链表的数组列表,其中文本中的每个单词后面都是链表中的单词。

想想这段文字:猫走向那棵红色的树。

我希望链接列表的数组列表是这样的:

猫红

|

猫行

|

|

红树

我现在拥有的是:

while(dataFile.hasNext()){
     secondWord = dataFile.next();
     nWords++;
     if(nWords % 1000 ==0) System.out.println(nWords+" words");

   //and put words into list if not already there
   //check if this word is already in the list
   if(follows.contains(firstWord)){
    //add the next word to it's linked list 
 ((LinkedList)(firstWord)).add(secondWord);
   }
   else{
      //create new linked list for this word and then add next word
      follows.add(new LinkedList<E>().add(firstWord));

  ((LinkedList)(firstWord)).add(secondWord);
   }
   //go on to next word                     
   firstWord = secondWord;
   }

它给了我很多错误。我该怎么做才能做到最好?(使用链表,我知道哈希表和二进制树更好,但我需要使用链表)

ArrayList不是外部列表的最佳数据结构,至少部分困难源于对列表列表的错误使用。

在您的实现中,假定follows是LinkedLists的ArrayList,声明如下:

ArrayList<LinkedList<String>> follows = new ArrayList<>();

follows.contains(firstWord)的结果永远不会为true,因为follows包含类型为LinkedList的元素,而不是String。firstWord是一个String,因此不会是follows的元素,而是作为follows的元素的ArrayList的第一个元素。

下面提供的解决方案对外部列表follows使用Map,或者更具体地使用HashMap。Map是优选的,因为当搜索第一个单词时,使用Map的平均查找时间将为O(1),而列表的平均查找速度为O(n)。

String firstWord = dataFile.next().toLowerCase();
Map<String, List<String>> follows = new HashMap<>();
int nWords = 0;
while (dataFile.hasNext())
{
    String secondWord = dataFile.next().toLowerCase();
    nWords++;
    if (nWords % 1000 == 0)
    {
        System.out.println(nWords + " words");
    }
    //and put words into list if not already there
    //check if this word is already in the list
    if (follows.containsKey(firstWord))
    {
        //add the next word to it's linked list
        List list = follows.get(firstWord);
        if (!list.contains(secondWord))
        {
            list.add(secondWord);
        }
    }
    else
    {
        //create new linked list for this word and then add next word
        List list = new LinkedList<String>();
        list.add(secondWord);
        follows.put(firstWord, list);
    }
    //go on to next word
    firstWord = secondWord;
}

地图将如下所示:

the: [cat, red]
cat: [walks]
to: [the]
red: [tree]
walks: [to]

我还对您的实现进行了以下更改:

  • 不要在下列单词列表中添加重复单词。请注意,Set将是更适合此任务的数据结构,但您明确指出了使用LinkedList的要求。

  • 使用String.toLowerCase()将所有字符串移到小写,以便"the"one_answers"the"得到同等处理。(请确保您也将此应用于firstWord的初始值,它不会出现在您提供的代码中。)

请注意,此解决方案和您最初的尝试都假定标点符号已被删除。

您不应该使用直接类实现,而应该使用它们的接口来简化开发(以及其他原因)。因此,请改为每隔一段时间进行类型转换,将变量声明为List,并在初始化时定义类。由于您还没有发布相关的代码来重新定义它,我可以给您举一个例子:

List<List<String>> listOfListOfString = new LinkedList<>(); //assuming Java 7 or later used
List<String> listOne = new ArrayList<>();
listOne.add("hello");
listOne.add("world");
listOfListOfString.add(listOne);
List<String> listTwo = new ArrayList<>();
listTwo.add("bye);
listTwo.add("world");
listOfListOfString.add(listTwo);
for (List<String> list : listOfListOfString) {
    System.out.println(list);
}

这将打印:

[hello, world]
[bye, world]

请注意,现在您可以将listOnelistTwo中任何一个的实现更改为LinkedList:

List<String> listOne = new LinkedList<>();
//...
List<String> listTwo = new LinkedList<>();

代码的行为也将相同。无需进行任何类型转换即可使其工作。

相关:

  • 这对";程序到接口"

相关内容

  • 没有找到相关文章

最新更新