简体   繁体   English

Java嵌套的For循环突然中断

[英]Java nested For-loop breaking abruptly

I'm a programmer enthusiast and have been learning Java for about a month. 我是一名程序员狂热者,已经学习Java大约一个月了。 So, I decided to take on a problem offered through r/dailyprogramming. 因此,我决定接受r / dailyprogramming提供的问题。 The link is below for those that are interested: 下面的链接针对那些感兴趣的人:

http://www.reddit.com/r/dailyprogrammer/comments/2nynip/2014121_challenge_191_easy_word_counting/ http://www.reddit.com/r/dailyprogrammer/comments/2nynip/2014121_challenge_191_easy_word_counting/

So far I have splitted the words into a String array called splitted. 到目前为止,我已经将单词拆分为一个名为splitd的String数组。 The words are all lowered cased and periods, commas, and some other common punctuation, resulting in an array filled with lowercase lettered words. 单词全部使用小写字母和句点,逗号和其他一些常见的标点符号,从而形成一个由小写字母单词组成的数组。 Currently I'm trying to count the number of occurence of each word by taking in the first word of the array that is not null and then checking each element and counting for each occurences. 当前,我正在尝试通过获取不为null的数组的第一个单词,然后检查每个元素并为每个出现次数进行计数,来计算每个单词的出现次数。 I used nested for loops and if statements to accomplish this. 我使用嵌套的for循环和if语句来完成此任务。 However, the program keeps abruptly stopping without returning any errors. 但是,该程序会突然停止而不会返回任何错误。 I'm hoping someone can explain to me why my code is abruptly stopping. 我希望有人可以向我解释为什么我的代码突然停止。

Everything works fine until this part of the code. 一切正常,直到代码的这一部分。

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

    if (splitted[i] != null) {

        word = splitted[i];
        System.out.println("Word is: " + word);

            for (int j = i; j < splitted.length; j++) {

                if (splitted[j].contains(word)) {

                    splitted[j] = null;
                    count++;
                }
            }

        System.out.println(word + ": " + count);
        count = 0;
    }           
}

This is the modified code with outputs at different points. 这是修改后的代码,输出在不同点。 I have checked for the array length and it is not out of bound. 我已经检查了数组长度,并且它没有超出范围。

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

    if (splitted[i] != null) {

        word = splitted[i];
        System.out.println("Word is: " + word);

            for (int j = i; j < splitted.length; j++) {

                System.out.printf("%d %s %B%n", j, splitted[j], splitted[j].contains(word));
                if (splitted[j].contains(word)) {

                    splitted[j] = null;
                    count++;
                }

                System.out.println(j + " is less than " + splitted.length);
            }

        System.out.println(word + ": " + count);
        count = 0;
    }
        System.out.println(splitted[i] + " " + i);          
}

Edited for more clarity: The problem is the program abruptly stopping after checking a null element in the array, despite j being less than splitted.length. 为更清晰起见,对其进行了编辑:问题是,尽管j小于splitted.length,但程序在检查数组中的null元素后突然停止。

Output: 输出:

Today was great hello stupid Today. Today was bad. Today was amazing. He is great. He was bad.    Now he is great! 
Word is: today
0 today TRUE
0 is less than 22
1 was FALSE
1 is less than 22
2 great FALSE
2 is less than 22
3 hello FALSE
3 is less than 22
4 stupid FALSE
4 is less than 22
5 today TRUE
5 is less than 22
6 today TRUE
6 is less than 22
7 was FALSE
7 is less than 22
8 bad FALSE
8 is less than 22
9 today TRUE
9 is less than 22
10 was FALSE
10 is less than 22
11 amazing FALSE
11 is less than 22
12 he FALSE
12 is less than 22
13 is FALSE
13 is less than 22
14 great FALSE
14 is less than 22
15 he FALSE
15 is less than 22
16 was FALSE
16 is less than 22
17 bad FALSE
17 is less than 22
18 now FALSE
18 is less than 22
19 he FALSE
19 is less than 22
20 is FALSE
20 is less than 22
21 great FALSE
21 is less than 22
today: 4
null 0
Word is: was
1 was TRUE
1 is less than 22
2 great FALSE
2 is less than 22
3 hello FALSE
3 is less than 22
4 stupid FALSE
4 is less than 22

Thanks, 谢谢,

The problem is that you don't check for null in your second for -loop: 问题是,你不检查null在你的第二个for -loop:

for (int j = i; j < splitted.length; j++) {
    if (splitted[j].contains(word)) {//what if splitted[j] is null?
        splitted[j] = null;
        count++;
    }
}

In case null is encountered, for instance because an earlier iteration has set the item to null , one gets a NullPointerException . 如果遇到null情况(例如,因为较早的迭代将该项设置为null ,则将获得NullPointerException

So you should use: 因此,您应该使用:

for (int j = i; j < splitted.length; j++) {
    if (splitted[j] != null && splitted[j].contains(word)) {//what if splitted[j] is null?
        splitted[j] = null;
        count++;
    }
}

There are however some other aspects with this code that are not completely right: 但是,此代码还有一些其他方面并不完全正确:

  • you probably should use equals instead of contains because "foobarqux".contains("bar") is true . 您可能应该使用equals而不是contains,因为"foobarqux".contains("bar")true
  • you can do this more efficiently (in O(n log n) ) time by either first sorting the values before counting, or use a HashMap<String,Integer> to count the instances. 您可以通过在计数之前先对值进行排序,或使用HashMap<String,Integer>对实例进行计数来更有效地(以O(n log n) )方式执行此操作。

Check this jdoodle . 检查这个jdoodle

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

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