시퀀스의 임의 위치에서 C/T의 가장 긴 연속 패턴과 중앙에서 C/T의 가장 긴 연속 패턴을 계산하는 방법
CCCCTGTTGCCAAACAATGC
TTTTCCCGCCTTGGCCTAC
TACACGGAACCTCTTTTTTTA
원하는 출력은 시퀀스의 어느 곳에서나 C/T의 가장 긴 연속 패턴과 중앙에서 시작하는 C/T의 가장 긴 연속 패턴을 계산하는 것입니다.
CCCCTGTTGCCAAACAATGC5 2
TTTTCCCGCCTTGGCCTAC7 5
TACACGGAACCTCTTTTTTTA10 10
첫 번째 행에는 5개의 연속된 C/T 패턴이 순서대로 있고 중앙에서 가장 긴 C/T 패턴은 2개입니다.
추신. 유사한 문제에 대한 해결책은 여기에 있습니다. 가장 긴 연속 패턴 계산
답변1
"중앙에서"라는 말은 "문자열의 중간 문자를 포함하는 시퀀스"를 의미한다고 가정합니다. 문자열의 중간 문자가 C도 T도 아니도록 테스트 데이터에 한 줄을 추가했습니다.
$ cat file
CCCCTGTTGCCAAACAATGC
TTTTCCCGCCTTTGGCCTAC
TACACGGAACCTCTTTTTTA
CATAAAAAAAAAAAAACTCT
솔루션은 패턴과 일치하는 match() 함수의 부산물로 설정되는 awk의 RSTART 및 RLENGTH 변수와 문자열에서 현재 위치를 추적하는 일부 알고리즘에 의존합니다.
awk '{
line = $0
max = max_ctr = 0
mid = int(length($0)/2)
idx = 1
while (match( substr(line,idx), /[CT]+/ )) {
if (RLENGTH > max) max = RLENGTH
if (idx <= mid && mid <= idx+RLENGTH) max_ctr = RLENGTH
idx += RSTART + RLENGTH - 1
}
print $0, max, max_ctr
}' file
산출
CCCCTGTTGCCAAACAATGC 5 2
TTTTCCCGCCTTTGGCCTAC 7 5
TACACGGAACCTCTTTTTTA 10 10
CATAAAAAAAAAAAAACTCT 4 0
답변2
"중심에서"가 "중심에 가장 가깝지만 반드시 통과할 필요는 없는 가장 긴 문자열"을 의미하는 경우 시도해 볼 수 있습니다.
awk '
{MID = int(length()/2);
MX = PTR = 0
T0 = $0
while (match ($0, /[CcTt]+/)) {if (RLENGTH > MX) MX = RLENGTH
SSTR = PTR + RSTART
SEND = SSTR + RLENGTH - 1
TMPS = SSTR - MID
TMPE = MID - SEND
if (SEND < MID) {P = TMPE; RES = RLENGTH}
else {if (SSTR <= MID) {P = 0; RES = RLENGTH}
else if ((P > TMPS) ||
(P == TMPS) && (RLENGTH > RES)) {P = TMPS; RES = RLENGTH}
}
PTR = SEND
$0 = substr ($0, RSTART + RLENGTH)
}
print T0, MX, RES
}
' file
정규식에서 정규식이 일치하는 줄까지 반복하고 포인터를 유지하여 원래 줄의 위치를 저장합니다. 이를 통해 문자열의 끝에서 중심까지 또는 중심에서 문자열의 시작까지의 문자 거리를 계산하고 최소 거리의 문자열 길이를 결과 변수에 할당합니다. 동일한 거리의 경우 가장 긴 길이를 유지합니다.
중심을 통과하는 패턴의 경우 결과는 이전에 제공된 샘플과 동일합니다.