diff --git a/.gitignore b/.gitignore
index 236a7c71..a80c53d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,3 +51,5 @@ buildNumber.properties
.mvn/timing.properties
!/.mvn/wrapper/maven-wrapper.jar
*_Practice.java
+
+htmlReport/
diff --git a/pom.xml b/pom.xml
index 4db680c0..3188f0ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,6 +60,15 @@
junit-jupiter-api
5.5.1
+
+
+
+ com.sun
+ tools
+ 1.8
+ system
+
+
diff --git a/src/main/java/com/ctci/arraysandstrings/IsUnique.java b/src/main/java/com/ctci/arraysandstrings/IsUnique.java
index 895d16b3..f6e91edb 100644
--- a/src/main/java/com/ctci/arraysandstrings/IsUnique.java
+++ b/src/main/java/com/ctci/arraysandstrings/IsUnique.java
@@ -6,46 +6,86 @@
*/
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 and it in the ASCII table.
+ *
+ * @param str Input string
+ * @return true if all characters are different from each other, otherwise false.
+ */
+ public static boolean isAllCharactersUniqueAndInASCII(String str) {
+ if (str == null || str.isEmpty()) {
+ return false;
+ }
+
+ int maxCharIndex = 128;
+ int stringLength = str.length();
+
+ if (stringLength > maxCharIndex) {
+ 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]) {
+ boolean[] characterTrack = new boolean[maxCharIndex]; // assuming the string contains only ASCII characters
+ for (int i = 0; i < stringLength; i++) {
+ int charIndex = str.charAt(i);
+ if (charIndex >= maxCharIndex
+ || characterTrack[charIndex]) {
return false;
}
- charSet[charVal] = true;
+
+ characterTrack[charIndex] = true;
}
return true;
}
- private static boolean hasAllUniqueCharactersWhenStringContainsAllLowercase(String s) {
+ /**
+ * Check whether the input string contains different individual characters, lowercase
+ * and in between 'a' and 'z'
+ *
+ * @param str Input string
+ * @return true if all characters are different from each other,lowercase and between 'a' and 'z', otherwise false.
+ */
+ public static boolean isAllCharactersUniqueAndLowercaseAndInAlphabet(String str) {
+ if (str == null
+ || str.isEmpty()
+ || str.length() > 26) {
+ return false;
+ }
+
int checker = 0;
- for (int i = 0; i < s.length(); i++) {
- int charValue = s.charAt(i) - 'a';
- if ((checker & (1 << charValue)) > 0) {
+ int stringLength = str.length();
+ for (int i = 0; i < stringLength; i++) {
+
+ char character = str.charAt(i);
+ if (!(character >= 'a' && character <= 'z')) {
+ return false;
+ }
+
+ int characterIndex = character - 'a';
+ int singleBitOnPosition = 1 << characterIndex ;
+
+ if ((checker & singleBitOnPosition) > 0) {
return false;
}
- checker |= (1 << charValue);
+
+ checker |= singleBitOnPosition; // checker = checker | singleBitOnPosition;
}
return true;
}
public static void main(String[] args) {
String s = "ram";
- System.out.println(hasAllUniqueCharacters(s));
+ System.out.println(isAllCharactersUniqueAndInASCII(s));
s = "rama";
- System.out.println(hasAllUniqueCharacters(s));
+ System.out.println(isAllCharactersUniqueAndInASCII(s));
s = "ramA";
- System.out.println(hasAllUniqueCharacters(s));
+ System.out.println(isAllCharactersUniqueAndInASCII(s));
System.out.println("-------");
s = "ram";
- System.out.println(hasAllUniqueCharactersWhenStringContainsAllLowercase(s));
+ System.out.println(isAllCharactersUniqueAndLowercaseAndInAlphabet(s));
s = "rama";
- System.out.println(hasAllUniqueCharactersWhenStringContainsAllLowercase(s));
+ System.out.println(isAllCharactersUniqueAndLowercaseAndInAlphabet(s));
// not working as the input contains different cases
s = "ramA";
- System.out.println(hasAllUniqueCharactersWhenStringContainsAllLowercase(s));
+ System.out.println(isAllCharactersUniqueAndLowercaseAndInAlphabet(s));
}
}
diff --git a/src/main/test/com/ctci/arraysandstrings/IsUniqueTest.java b/src/main/test/com/ctci/arraysandstrings/IsUniqueTest.java
new file mode 100644
index 00000000..ef373ded
--- /dev/null
+++ b/src/main/test/com/ctci/arraysandstrings/IsUniqueTest.java
@@ -0,0 +1,224 @@
+package com.ctci.arraysandstrings;
+
+import org.junit.jupiter.api.*;
+
+public class IsUniqueTest {
+
+ @Nested
+ @DisplayName("Test cases for isAllCharactersUniqueAndInASCII()")
+ class TestCasesForIsAllCharactersUniqueAndInASCII {
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_StringIsNull_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII(null));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_StringIsEmpty_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII(""));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_StringLengthSmallerOrEqual128_ReturnFalse() {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ for (int i = 0; i < 128; i++) {
+ stringBuilder.append((char) i);
+ }
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII(stringBuilder.toString()));
+
+ stringBuilder.setLength(0);
+ for (int i = 1; i < 127; i++) {
+ stringBuilder.append((char) i);
+ }
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII(stringBuilder.toString()));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_StringLengthLargerThan128_ReturnFalse() {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ for (int i = 0; i < 128; i++) {
+ stringBuilder.append((char) i);
+ }
+ stringBuilder.append("a");
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII(stringBuilder.toString()));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_DuplicateAtHead_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("aab"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("AAb"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("ááb"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("ÁÁb"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("1123456"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_DuplicateAtMiddle_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("abcbd"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("aBcBd"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("aưcưd"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("aƯcƯd"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("123436"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_DuplicateAtTail_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("aba"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("AbA"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("ăbă"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("ĂbĂ"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("1234566"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_OnlyOneCharacter_ReturnTrue() {
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII("a"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII("1"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII("A"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII("#"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_OnlyOneCharacter_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("á"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("Ô"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("€"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_InvalidString_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("ۇ"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndInASCII("áÂ"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndInASCII_ValidString_ReturnTrue() {
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII("aAb"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII("abcBd"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII("abA"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndInASCII(
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));
+ }
+ }
+
+ @Nested
+ @DisplayName("Test cases for isAllCharactersUniqueAndLowercaseAndInAlphabet()")
+ class TestCasesForIsAllCharactersUniqueAndLowercaseAndInAlphabet {
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_StringIsNull_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet(null));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_StringIsEmpty_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet(""));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_StringLengthSmallerOrEqual26_ReturnFalse() {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ for (int i = 97; i <= 122; i++) { // 'a' -> 'z'
+ stringBuilder.append((char) i);
+ }
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet(stringBuilder.toString()));
+
+ stringBuilder.setLength(0);
+ for (int i = 100; i <= 120; i++) { // 'a' -> 'z'
+ stringBuilder.append((char) i);
+ }
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet(stringBuilder.toString()));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_StringLengthLargerThan26_ReturnFalse() {
+ String a2z = "abcdefghijklmnopqrstuvwxyz";
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet(a2z + (char) 96)); // 96 => `
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet(a2z + (char) 123)); // 123 => {
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_Beyond_a2z_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("GH@"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("{} "));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("ááb"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("ÁÁb"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("1123456"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_DuplicateAtHead_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("aab"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("AAb"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("ááb"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("ÁÁb"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("1123456"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_DuplicateAtMiddle_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("abcbd"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("aBcBd"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("aưcưd"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("aƯcƯd"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("123436"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_DuplicateAtTail_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("aba"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("AbA"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("ăbă"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("ĂbĂ"));
+
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("1234566"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_OnlyOneCharacter_ReturnTrue() {
+ for (int i = 97; i <= 122; i++) {
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet(String.valueOf((char) i)));
+ }
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_OnlyOneCharacter_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("A"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("á"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("Ô"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("€"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_InvalidString_ReturnFalse() {
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("ۇ"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("áÂ"));
+ Assertions.assertFalse(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("aB"));
+ }
+
+ @Test
+ public void isAllCharactersUniqueAndLowercaseAndInAlphabet_ValidString_ReturnTrue() {
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("mwq"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("fwoklt"));
+ Assertions.assertTrue(IsUnique.isAllCharactersUniqueAndLowercaseAndInAlphabet("abcdefghijklmnopqrstuvwxyz"));
+ }
+ }
+
+}