Repository: TheAlgorithms/Java
Pull request #4210 (2023-06-02 14:39:20)

fix: `CountWords.secondaryWordCount`
The original implementation of [`secondaryWordCount`](https://github.com/TheAlgorithms/Java/blob/22002c9939fdeff1d7ef659a688ad7f396dd564a/src/main/java/com/thealgorithms/others/CountWords.java#L40) always returns `1` for non-empty input (note that the spaces are always removed).

This PR:
- fixes the mentioned issue,
- adds tests,
- does some basic refactoring.  

<!-- For completed items, change [ ] to [x] -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.



Patch:
diff --git a/src/main/java/com/thealgorithms/others/CountWords.java b/src/main/java/com/thealgorithms/others/CountWords.java
index 2bbfe08e..5117b83b 100644
--- a/src/main/java/com/thealgorithms/others/CountWords.java
+++ b/src/main/java/com/thealgorithms/others/CountWords.java
@@ -3,32 +3,34 @@ package com.thealgorithms.others;
 import java.util.Scanner;
 
 /**
- * You enter a string into this program, and it will return how many words were
- * in that particular string
- *
  * @author Marcus
  */
-public class CountWords {
-
-    public static void main(String[] args) {
-        Scanner input = new Scanner(System.in);
-        System.out.println("Enter your text: ");
-        String str = input.nextLine();
-
-        System.out.println("Your text has " + wordCount(str) + " word(s)");
-        System.out.println(
-            "Your text has " + secondaryWordCount(str) + " word(s)"
-        );
-        input.close();
+final public class CountWords {
+    private CountWords() {
     }
 
-    private static int wordCount(String s) {
+    /**
+     * @brief counts the number of words in the input string
+     * @param s the input string
+     * @return the number of words in the input string
+     */
+    public static int wordCount(String s) {
         if (s == null || s.isEmpty()) {
             return 0;
         }
         return s.trim().split("[\\s]+").length;
     }
 
+    private static String removeSpecialCharacters(String s) {
+        StringBuilder sb = new StringBuilder();
+        for (char c : s.toCharArray()) {
+            if (Character.isLetterOrDigit(c) || Character.isWhitespace(c)) {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
     /**
      * counts the number of words in a sentence but ignores all potential
      * non-alphanumeric characters that do not represent a word. runs in O(n)
@@ -37,17 +39,10 @@ public class CountWords {
      * @param s String: sentence with word(s)
      * @return int: number of words
      */
-    private static int secondaryWordCount(String s) {
-        if (s == null || s.isEmpty()) {
+    public static int secondaryWordCount(String s) {
+        if (s == null) {
             return 0;
         }
-        StringBuilder sb = new StringBuilder();
-        for (char c : s.toCharArray()) {
-            if (Character.isLetter(c) || Character.isDigit(c)) {
-                sb.append(c);
-            }
-        }
-        s = sb.toString();
-        return s.trim().split("[\\s]+").length;
+        return wordCount(removeSpecialCharacters(s));
     }
 }


Test patch:
diff --git a/src/test/java/com/thealgorithms/others/CountWordsTest.java b/src/test/java/com/thealgorithms/others/CountWordsTest.java
new file mode 100644
index 00000000..a2b0c03d
--- /dev/null
+++ b/src/test/java/com/thealgorithms/others/CountWordsTest.java
@@ -0,0 +1,38 @@
+package com.thealgorithms.others;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.HashMap;
+import org.junit.jupiter.api.Test;
+
+
+class CountWordsTest {
+    @Test
+    public void testWordCount() {
+        HashMap<String, Integer> testCases = new HashMap<>();
+        testCases.put("", 0);
+        testCases.put(null, 0);
+        testCases.put("aaaa bbb cccc", 3);
+        testCases.put("note  extra     spaces   here", 4);
+        testCases.put(" a  b c d  e    ", 5);
+
+        for (final var tc : testCases.entrySet()) {
+            assertEquals(CountWords.wordCount(tc.getKey()), tc.getValue());
+        }
+    }
+
+    @Test
+    public void testSecondaryWordCount() {
+        HashMap<String, Integer> testCases = new HashMap<>();
+        testCases.put("", 0);
+        testCases.put(null, 0);
+        testCases.put("aaaa bbb cccc", 3);
+        testCases.put("this-is-one-word!", 1);
+        testCases.put("What, about, this? Hmmm----strange", 4);
+        testCases.put("word1 word-2 word-3- w?o,r.d.@!@#$&*()<>4", 4);
+
+        for (final var tc : testCases.entrySet()) {
+            assertEquals(CountWords.secondaryWordCount(tc.getKey()), tc.getValue());
+        }
+    }
+}