简体   繁体   中英

Java nested For-loop breaking abruptly

I'm a programmer enthusiast and have been learning Java for about a month. So, I decided to take on a problem offered through 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/

So far I have splitted the words into a String array called splitted. 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. I used nested for loops and if statements to accomplish this. 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.

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:

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 .

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 .
  • 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.

Check this jdoodle .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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