2012-04-01 2 views
2

서브 시퀀스의 첫 번째 절반이 두 번째 절반과 동일하도록 가장 긴 서브 시퀀스를 찾고 싶다고 가정 해보십시오.문자열에서 가장 긴 유사한 서브 시퀀스를 찾으십시오.

예 : 문자열 abkcjadfbck에서 abcabc는 첫 번째와 두 번째 절반에서 반복되므로 결과는 abcabc입니다. 교반에 aaa 결과는 aa입니다.

+0

나는 그것을 얻지 못한다. 첫 번째 문자열에서'abc'는 어디에 있습니까? 그리고 왜 두 번째 문자열의 결과가'aaa '가 아닌가? 분명히 그것은 더 길다. –

+1

하위 시퀀스는 인덱스가 연속적이어야 함을 의미하지는 않습니다. 결과 aa는 [index 0, index 1], [index 1, index 2] 또는 [index 0, index 2]입니다. – DaveFar

+0

aaa는 "aa"결과가 있습니다. 왜냐하면 "aa"는 전반이 후반과 동일하기 때문입니다. – test

답변

1

이 작업은 잘 알려진 두 가지 문제의 조합으로 간주 될 수 있습니다.

  1. 두 시퀀스 사이의 일부 지점을 미리 알고 있다면 두 문자열에 가장 잘 맞는 것을 찾아야합니다. 이것은 Pairwise alignment 문제입니다. 다양한 동적 프로그래밍 방법으로 O (N) 시간에이를 해결합니다.
  2. 문자열을 최적으로 분할해야하는 지점을 찾으려면 Golden section search 또는 피보나치 검색을 사용할 수 있습니다. 이러한 알고리즘은 O (log N) 시간의 복잡성을 갖습니다.
+0

그래서, 내가 ur 메서드에서 이해하는 것은 .. i = 1 : n에서 두 개의 문자열을 만들고 그 위에 가장 긴 공통 부분 시퀀스를 수행합니다. 따라서, 비슷한 반쪽으로 가장 긴 서브 시퀀스를 찾는 것은 n * (n * n)의 순서가됩니다. 그러나 가능한 모든 문자열을 생성 할 수 있습니까? 예를 들어, aaa의 경우 3 개의 해당 문자열을 사용할 수 있습니다. aa, aa, aa. 두 번째 "a", 첫 번째 "a"와 세 번째 "a", 두 번째 "a"와 세 번째 "a") – test

+0

이러한 알고리즘을 사용하여 가장 긴 서브 시퀀스를 검색하는 것은 O (N^2 log N)이기 때문에 O 골든 섹션 검색은 가능한 모든 위치에서 문자열을 분리 할 필요가 없습니다. 그러나 이것은 모든 서브 시퀀스를 얻는 것을 허용하지 않습니다. 모든 하위 시퀀스를 생성하는 것은 완전히 다른 작업이며 일부 다른 방법으로 해결해야합니다. –

0

inputString을 통한 첫 번째 전달에서 각 문자가 발생하는 빈도를 계산하고 발생 빈도가있는 문자를 제거 할 수 있습니다.

input: inputString 
data strucutres: 
Set<Triple<char[], Integer, Integer>> potentialSecondWords; 
Map<Char, List<Integer>> lettersList; 

for the characters c with increasing index h in inputString do 
    if (!lettersList.get(c).isEmpty()) { 
    for ((secondWord, currentIndex, maxIndex) in potentialSecondWords) { 
     if (there exists a j in lettersList.get(c) between currentIndex and maxIndex) { 
     update (secondWord, currentIndex, maxIndex) by adding c to secondWord and replacing currentIndex with j; 
     } 
    } 
    if potentialSecondWords contains a triple whose char[] is equal to c, remove it; 
    put new Triple with value (c,lettersList.get(c).get(0), h-1) into potentialSecondWords; 
    } 
    lettersList.get(c).add(h); 
} 
find the largest secondWord in potentialSecondWords and output secondWord twice; 

그래서이 알고리즘은 의미가 각 인덱스, 현재 인덱스에서 시작하여 잠재적 인 두 번째 단어를 나타내는 트리플에 대한 생성, 배열을 통해 한 번 통과하고, 모든 잠재적 인 두 번째 단어를 업데이트합니다.

적절한 목록 구현 및 n이 inputString의 크기 인 경우이 알고리즘은 최악의 런타임 O (n²)를가집니다.^n.

+0

알 고를 설명해 주시겠습니까? – test

관련 문제