카톡방에서 python은 'abc' * 5와 같은 문법이 있는데 자바에는 없는지 물어보셨습니다. java 8에서는 어떻게 쓰는지 잘 모르겠습니다. 아마, 이런 식으로 쓰지 않을까 싶습니다.

 

 "abc"를 10번 반복하기 위해서, StringBuilder의 append 메소드를 썼습니다. abc를 10번 반복한다는 것이, abc를 10회 뒤에 추가하는 concat과 같기 때문입니다. 다음에, StringBuilder를 toString으로 변환한 다음에, 출력합니다. 4 ~ 5줄 정도에 구현할 수 있습니다.

 

 실행 결과는 위와 같이 나옵니다. 그런데, java 11부터는 이렇게 하지 않으셔도 됩니다.

 


 

 

 repeat 메서드는 반복 횟수만 넣으면 됩니다. 6번째 줄의 s.repeat(10)은 문자열 s를 10번 반복한 결과를 리턴합니다. 더 이상의 설명이 필요 없고, 결과만 보도록 합시다.

 

  정말 abc가 10번 반복 되었어요. 4 ~ 5줄의 복잡한 코드에 비하면, 상당히 간결해 졌네요.

 

 

 시간 복잡도는 어떻게 될까요? 위 프로그램은 "abc"를 100만번 반복 시킨 문자열을 돌려준 다음에, 그 문자열의 길이를 계산합니다.

 

 빠르게 300만이라는 결과가 나왔습니다. 이로 미루어 보았을 때, 시간 복잡도는 반복 횟수를 r이라 하고, 타겟 문자열을 s라 했을 때, O(r|s|)임을 알 수 있습니다. r|s|의 곱이 300만이고, 이것은 1억보다 매우 작으니 순식간에 돌게 됩니다.

 


 대체 repeat는 어느 경우에 쓸 수 있을까요? 원형 문자열을 다룰 때 많이 쓰입니다. 특히, 문자열 s 뒤에 s를 붙이는 패턴은 문자열 알고리즘을 적용할 때도, 단순 문자열 처리 문제에서도 매우 흔하게 보이는 패턴입니다. 이 문제를 보도록 하겠습니다. 5555번 반지는, 패턴의 길이가 10 이하이고, 반지의 문자열 길이가 10입니다.

 

 그런데, 문제는 원형으로 돌아간다는 것입니다.

 

 그러면 aaaaaaaaab에서 ba 패턴을 찾을 경우에, 문제가 될 겁니다. 분명히 반지는 시작과 끝이 연결이 되어 있고, b와 a는 연결이 되어 있는데, 단순히 aaaaaaaaab에서 ba를 indexOf 등으로 찾으면 없다고 뜰 겁니다. 왜? aaaaaaaaab는 ba를 부분 문자열로 가지지 않기 때문입니다.

 

 시작과 끝이 연결된 경우에는, 문자열을 한 번 더 repeat를 시킵니다.

 

 그러면, b와 a가 연결 되어 있다는 것도 표현할 수 있게 됩니다. 이것을 java의 repeat 메서드를 이용해서 구현해 봅시다.

 

 

 패턴과 ring의 개수를 각각 7번째 줄과 8번째 줄에서 입력 받습니다.

 

 다음, n번 loop를 돌면서, 입력 받은 데이터를 2번 반복시킨 문자열에서, indexOf 메서드로 찾습니다. 만약에 str에서 패턴이 찾아지면 ans를 하나 더합니다.

 

 예제 3에 대해서 2가 나왔음을 확인했습니다.