diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/stringrotation/StringRotation.java b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/stringrotation/StringRotation.java new file mode 100644 index 0000000000..862c745c9e --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/stringrotation/StringRotation.java @@ -0,0 +1,123 @@ +package com.baeldung.algorithms.stringrotation; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class StringRotation { + + public static boolean doubledOriginContainsRotation(String origin, String rotation) { + if (origin.length() == rotation.length()) { + return origin.concat(origin) + .contains(rotation); + } + + return false; + } + + public static boolean isRotationUsingCommonStartWithOrigin(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + + List indexes = IntStream.range(0, origin.length()) + .filter(i -> rotation.charAt(i) == origin.charAt(0)) + .boxed() + .collect(Collectors.toList()); + + for (int startingAt : indexes) { + if (isRotation(startingAt, rotation, origin)) { + return true; + } + } + } + + return false; + } + + static boolean isRotation(int startingAt, String rotation, String origin) { + + for (int i = 0; i < origin.length(); i++) { + if (rotation.charAt((startingAt + i) % origin.length()) != origin.charAt(i)) { + return false; + } + } + + return true; + } + + public static boolean isRotationUsingQueue(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + return checkWithQueue(origin, rotation); + } + + return false; + } + + static boolean checkWithQueue(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + + Queue originQueue = getCharactersQueue(origin); + + Queue rotationQueue = getCharactersQueue(rotation); + + int k = rotation.length(); + while (k > 0 && null != rotationQueue.peek()) { + k--; + char ch = rotationQueue.peek(); + rotationQueue.remove(); + rotationQueue.add(ch); + if (rotationQueue.equals(originQueue)) { + return true; + } + } + } + + return false; + } + + static Queue getCharactersQueue(String origin) { + return origin.chars() + .mapToObj(c -> (char) c) + .collect(Collectors.toCollection(LinkedList::new)); + } + + public static boolean isRotationUsingSuffixAndPrefix(String origin, String rotation) { + + if (origin.length() == rotation.length()) { + return checkPrefixAndSuffix(origin, rotation); + } + + return false; + } + + static boolean checkPrefixAndSuffix(String origin, String rotation) { + if (origin.length() == rotation.length()) { + + for (int i = 0; i < origin.length(); i++) { + if (origin.charAt(i) == rotation.charAt(0)) { + if (checkRotationPrefixWithOriginSuffix(origin, rotation, i)) { + if (checkOriginPrefixWithRotationSuffix(origin, rotation, i)) + return true; + } + } + } + + } + + return false; + } + + private static boolean checkRotationPrefixWithOriginSuffix(String origin, String rotation, int i) { + return origin.substring(i) + .equals(rotation.substring(0, origin.length() - i)); + } + + private static boolean checkOriginPrefixWithRotationSuffix(String origin, String rotation, int i) { + return origin.substring(0, i) + .equals(rotation.substring(origin.length() - i)); + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/stringrotation/StringRotationUnitTest.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/stringrotation/StringRotationUnitTest.java new file mode 100644 index 0000000000..5558c6ca9f --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/stringrotation/StringRotationUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.algorithms.stringrotation; + +import static com.baeldung.algorithms.stringrotation.StringRotation.doubledOriginContainsRotation; +import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingCommonStartWithOrigin; +import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingQueue; +import static com.baeldung.algorithms.stringrotation.StringRotation.isRotationUsingSuffixAndPrefix; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class StringRotationUnitTest { + + @Test + void givenOriginAndRotationInput_whenCheckIfOriginContainsRotation_thenIsRotation() { + assertTrue(doubledOriginContainsRotation("abcd", "cdab")); + assertTrue(doubledOriginContainsRotation("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckIfOriginContainsRotation_thenNoRotation() { + assertFalse(doubledOriginContainsRotation("abcd", "bbbb")); + assertFalse(doubledOriginContainsRotation("abcd", "abcde")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingCommonStartWithOrigin_thenIsRotation() { + assertTrue(isRotationUsingCommonStartWithOrigin("abcd", "cdab")); + assertTrue(isRotationUsingCommonStartWithOrigin("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingCommonStartWithOrigin_thenNoRotation() { + assertFalse(isRotationUsingCommonStartWithOrigin("abcd", "bbbb")); + assertFalse(isRotationUsingCommonStartWithOrigin("abcd", "abcde")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingQueues_thenIsRotation() { + assertTrue(isRotationUsingQueue("abcd", "cdab")); + assertTrue(isRotationUsingQueue("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingQueues_thenNoRotation() { + assertFalse(isRotationUsingQueue("abcd", "bbbb")); + assertFalse(isRotationUsingQueue("abcd", "abcde")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingSuffixAndPrefix_thenIsRotation() { + assertTrue(isRotationUsingSuffixAndPrefix("abcd", "cdab")); + assertTrue(isRotationUsingSuffixAndPrefix("abcd", "abcd")); + } + + @Test + void givenOriginAndRotationInput_whenCheckingUsingSuffixAndPrefix_thenNoRotation() { + assertFalse(isRotationUsingSuffixAndPrefix("abcd", "bbbb")); + assertFalse(isRotationUsingSuffixAndPrefix("abcd", "abcde")); + } +}