0

程序说明:

我有我的这个程序,它旨在从文件(大文件)中读取每个单词,然后检查单词是否已经存在于保留唯一单词的单词数组中。如果不是,则将单词添加到数组的末尾,并将 +1 添加到 uniquewordcounter 以及同一索引处的计数数组。如果单词已经位于数组中的某个位置,它应该找到索引-数字,并在计数数组中的相同索引号上将值增加 1。当文件有更多内容时,它应该这样做。我也不允许使用 HashMaps。

但是,我的程序在读取文件时确实进入了无限循环,并且uniquewords 的计数很容易在眨眼间超过 100.000,但它应该最大为 5000...

这是代码:

class Oblig3A{
    public static void main(String[]args){

    OrdAnalyse oa = new OrdAnalyse();
    String filArgs=args[0];
    oa.analyseMetode(filArgs);
    }
}

class OrdAnalyse{
    void analyseMetode(String filArgs){

    //Begins with naming all of the needed variables
    Scanner input, innfil;
    String[] ord, fortelling;
    int[] antall;
    int antUnikeOrd, totalSum;
    PrintWriter utfil;

    //Declaring most of them.
    input=new Scanner(System.in);
    ord=new String[5000];
    antall=new int[5000];
    antUnikeOrd=0;
    totalSum=0;
    try{
        innfil=new Scanner(new File(filArgs));



    //The problem is located here somewhere:
        while(innfil.hasNext()){
        fortelling=innfil.nextLine().toLowerCase().split(" ");

        ord[0]=innfil.next().toLowerCase();

            for(int i=0; i<fortelling.length; i++){
            for(int j=0; j<5000; j++){
            if(fortelling[i].equals(ord[j])){
                antall[j]+=1;
                System.out.print("heo");
            }else{
                ord[j]=fortelling[i];
                antall[j]+=1;
                antUnikeOrd+=1;
                }
            System.out.println(ord.length);
            System.out.println(antUnikeOrd);

            }
        }
        }
        innfil.close();
    }catch(Exception e){
        e.printStackTrace();
    }

   // Here the program will write all the info acquired above into a file called Oppsummering.txt, which it will make.
    try{
        utfil=new PrintWriter(new File("Oppsummering.txt"));

        for(int i=0; i<antall.length; i++){
        totalSum+=antall[i];
        }

        utfil.println("Antall ord lest: " +totalSum+ " og antall unike ord: "+antUnikeOrd);

        for(int i=0; i<ord.length; i++){

        utfil.println(ord[i]+("  ")+antall[i]);
        }
        utfil.close();
    }catch(Exception e){
        e.printStackTrace();
    }
    }
}
4

3 回答 3

2
/The problem is located here somewhere:
    Scanner keepTrack=infill.next();
    while(keepTrack.next().Equals(null)){
    fortelling=innfil.nextLine().toLowerCase().split(" ");

    ord[0]=innfil.next().toLowerCase();

        for(int i=0; i<fortelling.length; i++){
        for(int j=0; j<5000; j++){
        if(fortelling[i].equals(ord[j])){
            antall[j]+=1;
            System.out.print("heo");
        }else{
            ord[j]=fortelling[i];
            antall[j]+=1;
            antUnikeOrd+=1;
            }
        System.out.println(ord.length);
        System.out.println(antUnikeOrd);

        }
    }
    infill=infill.next();
    keepTrack=infill;
    }
    innfil.close();
}

试试这个,我不确定它是否有效!

我认为问题在于你只循环一个元素而不是所有元素。

祝你好运!!!

于 2013-10-17T09:23:38.707 回答
1

对于您的问题,我没有直接的答案,但我为您提供了工作和更简单的解决方案。我必须承认我很懒,对像我这样的人来说分析你的代码很重要:)部分是因为它不是英文的,部分是因为如果你使用了正确的容器,代码可能会简单得多。我已经用较小的文件测试了你的代码,它也永远循环,所以大小无关紧要。

正如我所说,如果使用了适当的容器,它可以做得更简单。所以这是我的解决方案:

    Map<String, Integer> wordsMap = new HashMap<String, Integer>();

    Scanner scanner = new Scanner(new File("C:\\temp\\input.txt"));
    while(scanner.hasNext()){
        String word = scanner.next();
        wordsMap.put(word ,wordsMap.containsKey( word ) ? wordsMap.get( word ) + 1 : 1);
    }

    System.out.println("Total number of unique words: "+wordsMap.size());
    for( String word : wordsMap.keySet()){
        System.out.println("Word \""+word+"\" occurs "+wordsMap.get(word)+" times.");
    }

计数逻辑在 while 循环中。打印发生在 for 循环中,您可以使用文件更改系统输出,您应该没问题

于 2013-10-17T09:26:06.040 回答
0

这里有几个不同的问题会阻止您的程序按预期工作。首先,您对扫描仪的使用并没有给您预期的结果。假设我们有一个非常简单的输入文件,如下:

apple banana carrot
alligator baboon crocodile

首先,扫描仪位于文件的开头,如下所示:

|apple banana carrot
alligator baboon crocodile

当您调用.nextLine()扫描仪时,扫描仪会将其光标移到行尾并返回它传递的所有数据。所以fortelling设置为["apple", "banana", "carrot"]并且扫描仪位于第二行的开头,如下所示:

apple banana carrot
|alligator baboon crocodile

因此,当您调用 时.next()ord[0]将设置为“鳄鱼”并再次移动光标。扫描仪是不可倒带的,因此如果您已经使用下一个...方法之一读取了一些数据,您将无法使用同一扫描仪再次读取它。

您的第二个问题是循环内的逻辑。fortelling[i].equals(ord[j])将始终评估为假,因为其中没有一个字符串fortelling是“鳄鱼”。因此,始终执行以下行:

ord[j]=fortelling[i];
antall[j]+=1;
antUnikeOrd+=1;

由于您的内部循环,这些行将针对文件第一行中的每个单词重复 5000 次。因此,在外循环的第一次迭代之后,变量将如下所示:

ord : [ "apple", "apple", "apple", "apple", "apple", ... ]
antall : [ 1, 1, 1, 1, 1, ... ]
antUnikeOrd : 5000

在第二个之后它将是:

ord : [ "banana", "banana", "banana", "banana", "banana", ... ]
antall : [ 2, 2, 2, 2, 2, ... ]
antUnikeOrd : 10000

然后:

ord : [ "carrot", "carrot", "carrot", "carrot", "carrot", ... ]
antall : [ 2, 2, 2, 2, 2, ... ]
antUnikeOrd : 15000

这就是为什么您的唯一词数量增长如此之快。您处理的每个单词都会添加 5000。即使不存在扫描仪问题,这里的逻辑也不正确。如果一个单词与现有单词匹配,您只想执行一次操作,而不是 5000 次。一个恰当的break声明可能会解决这个问题。

此外,您正在更改ord[0]while 循环的每次迭代的值。如果这个数组应该是一个唯一词的列表,这是不正确的。中的每个项目ord都应设置一次且仅设置一次。

我并不是要让这成为一个大型的代码审查,但是你去吧。希望对你有帮助!

于 2013-10-17T12:23:22.893 回答