Check if two strings are rotations of each other [BAEL-7493] (#15864)
* feat: string rotation * fix: test names
This commit is contained in:
parent
fcb6efbf00
commit
c5a3c01108
@ -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<Integer> 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<Character> originQueue = getCharactersQueue(origin);
|
||||||
|
|
||||||
|
Queue<Character> 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<Character> 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));
|
||||||
|
}
|
||||||
|
}
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user