diff --git a/src/main/java/com/ctci/arraysandstrings/IsUnique.java b/src/main/java/com/ctci/arraysandstrings/IsUnique.java index 895d16b3..e509102f 100644 --- a/src/main/java/com/ctci/arraysandstrings/IsUnique.java +++ b/src/main/java/com/ctci/arraysandstrings/IsUnique.java @@ -1,21 +1,62 @@ package com.ctci.arraysandstrings; +import java.util.HashSet; +import java.util.Set; + /** * @author rampatra * @since 18/11/2018 */ public class IsUnique { - private static boolean hasAllUniqueCharacters(String str) { - if (str == null || str.length() > 128) return false; + /** + * Check whether the input string contains different individual characters in the ASCII table. + * + * @param inputString Input string + * @return true if all characters are different from each other, otherwise false. + */ + public static boolean hasDifferentIndividualCharacters(String inputString) { + int maxCharacterDecimal = 128; + + if (inputString == null + || inputString.isEmpty() + || inputString.length() > maxCharacterDecimal) { + return false; + } + + boolean[] characterTrack = new boolean[maxCharacterDecimal]; + + int inputStringLength = inputString.length(); + for (int i = 0; i < inputStringLength; i++) { + int charInDecimal = inputString.charAt(i); + + if (charInDecimal >= maxCharacterDecimal + || characterTrack[charInDecimal]) { + return false; + } + + characterTrack[charInDecimal] = true; + } + return true; + } + + /** + * Check whether the input string contains different individual characters. + * + * @param inputString Input string + * @return true if all characters are different from each other, otherwise false. + */ + public static boolean hasAllUniqueCharactersEnhancement(String inputString) { + if (inputString == null || inputString.isEmpty()) { + return false; + } - boolean[] charSet = new boolean[128]; // assuming the string contains only ASCII characters - for (int i = 0; i < str.length(); i++) { - int charVal = str.charAt(i); - if (charSet[charVal]) { + Set charSet = new HashSet<>(); + char[] inputStingArr = inputString.toCharArray(); + for (char c : inputStingArr) { + if (!charSet.add(c)) { return false; } - charSet[charVal] = true; } return true; } @@ -34,11 +75,11 @@ private static boolean hasAllUniqueCharactersWhenStringContainsAllLowercase(Stri public static void main(String[] args) { String s = "ram"; - System.out.println(hasAllUniqueCharacters(s)); + System.out.println(hasDifferentIndividualCharacters(s)); s = "rama"; - System.out.println(hasAllUniqueCharacters(s)); + System.out.println(hasDifferentIndividualCharacters(s)); s = "ramA"; - System.out.println(hasAllUniqueCharacters(s)); + System.out.println(hasDifferentIndividualCharacters(s)); System.out.println("-------"); s = "ram"; System.out.println(hasAllUniqueCharactersWhenStringContainsAllLowercase(s)); diff --git a/src/main/java/com/ctci/arraysandstrings/IsUniqueTest.java b/src/main/java/com/ctci/arraysandstrings/IsUniqueTest.java new file mode 100644 index 00000000..280f57f3 --- /dev/null +++ b/src/main/java/com/ctci/arraysandstrings/IsUniqueTest.java @@ -0,0 +1,112 @@ +package com.ctci.arraysandstrings; + +import org.junit.jupiter.api.*; + +public class IsUniqueTest { + + @Nested + @DisplayName("Test cases for hasDifferentIndividualCharacters() method") + class TestCasesForHasDifferentIndividualCharacters { + + @Test + public void testHasDifferentIndividualCharacters_StringIsNull_ReturnFalse() { + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters(null)); + } + + @Test + public void testHasDifferentIndividualCharacters_StringIsEmpty_ReturnFalse() { + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("")); + } + + @Test + public void testHasDifferentIndividualCharacters_StringLengthSmallerOrEqual128_ReturnFalse() { + StringBuilder stringBuilder = new StringBuilder(); + + for (int i = 0; i < 128; i++) { + stringBuilder.append((char) i); + } + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters(stringBuilder.toString())); + + stringBuilder.setLength(0); + for (int i = 1; i < 127; i++) { + stringBuilder.append((char) i); + } + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters(stringBuilder.toString())); + } + + @Test + public void testHasDifferentIndividualCharacters_StringLengthLargerThan128_ReturnFalse() { + StringBuilder stringBuilder = new StringBuilder(); + + for (int i = 0; i < 128; i++) { + stringBuilder.append((char) i); + } + stringBuilder.append("a"); + + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters(stringBuilder.toString())); + } + + @Test + public void testHasDifferentIndividualCharacters_DuplicateAtHead_ReturnFalse() { + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("aab")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("AAb")); + + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("ááb")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("ÁÁb")); + + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("1123456")); + } + + @Test + public void testHasDifferentIndividualCharacters_DuplicateAtMiddle_ReturnFalse() { + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("abcbd")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("aBcBd")); + + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("aưcưd")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("aƯcƯd")); + + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("123436")); + } + + @Test + public void testHasDifferentIndividualCharacters_DuplicateAtTail_ReturnFalse() { + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("aba")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("AbA")); + + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("ăbă")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("ĂbĂ")); + + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("1234566")); + } + + @Test + public void testHasDifferentIndividualCharacters_OnlyOneCharacter_ReturnTrue() { + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters("a")); + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters("1")); + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters("A")); + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters("#")); + } + + @Test + public void testHasDifferentIndividualCharacters_OnlyOneCharacter_ReturnFalse() { + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("á")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("Ô")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("€")); + } + + @Test + public void testHasDifferentIndividualCharacters_InvalidString_ReturnFalse() { + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("€á")); + Assertions.assertFalse(IsUnique.hasDifferentIndividualCharacters("áÂ")); + } + + @Test + public void testHasDifferentIndividualCharacters_ValidString_ReturnTrue() { + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters("aAb")); + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters("abcBd")); + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters("abA")); + Assertions.assertTrue(IsUnique.hasDifferentIndividualCharacters( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); + } + } +} \ No newline at end of file