문자를 반복하지 않고 해당 하위 문자열의 길이를 반환하지 않고 가장 긴 하위 문자열을 찾고 있습니다.
예를 들어, 다음 입력이 주어지면:
abcbdbdsdfng
출력은 다음과 같아야 합니다.
5
설명하다:
- 첫 번째 문자열은
abc
(길이 3) 입니다. - 다음 가능성은
cbd
(길이 3) 입니다. - 다음 가능성은
db
(길이 2) 입니다. - 다음 가능성은
bds
(길이 3) 입니다. - 다음 가능성은
sdfng
(길이 5) 입니다.
따라서 이 예에는 sdfng
고유 문자만 포함하는 가장 긴 하위 문자열이 있습니다.
답변1
POSIX sh
구문을 사용하고 awk
유틸리티를 한 번 호출하십시오.
<input awk '
{
cur = longest = ""
n = l = 0
while ($0 != "") {
c = substr($0, 1, 1)
if (i = index(cur, c)) {
cur = substr(cur, i+1)
l -= i
}
$0 = substr($0, 2)
cur = cur c
if (++l > n) {
n = l
longest = cur
}
}
printf "\"%s\" (%d)\n", longest, n
}'
답변2
셸(예, 이식 가능) 언어에서는 반복 문자가 없는 가장 긴 부분 문자열(LSRC)을 찾는 것이 매우 간단합니다 sh
(빠르지 않으며 셸의 텍스트 처리가 일반적으로 느립니다).
#!/bin/sh
str=$1 longest='' teststr=''
while [ "${str}" ]; do
c=${str%"${str#?}"} # extract one char to test it.
str=${str#?} # remove the character from str.
teststr=${teststr#*"$c"}$c # Build teststr by appending $c
# remove leading repeated char.
l1=${#longest} # length of longest found
l2=${#teststr} # length of tested string
if [ "$l1" -lt "$l2" ] # if tested is longer than longest
then longest=$teststr # store it in longest.
fi
done
echo "$longest ${#longest}"; # print longest found and length.
설명을 위한 두 가지 일반적인 알고리즘이 있습니다.반복되는 문자가 없는 가장 긴 부분 문자열 찾기
"슬라이딩 윈도우" 방법으로도 알려진 두 번째 방법은 다음과 같이 작동합니다.
str
(maketeststr
및 비어 있음)longest
의 전체 입력 문자열로 시작합니다 . 그런 다음 루프에서 다음을 수행합니다.c
의 앞부분에서 문자( )를 추출합니다str
.c
중복이 있는지 확인하세요teststr
.- 반복 되면
c
계속해서 이전 문자를 삭제하세요teststr
. c
반복되지 않는 항목 이 하나 있습니다teststr
.c
에 추가하세요teststr
.teststr
보다 긴지 확인하세요longest
. 그렇다면 문자열을longest
.- 더 이상 문자가 없으면
str
루프가 종료됩니다 .
3, 4, 5단계는 다음과 같이 단순화될 수 있습니다.하나문자열 작업: " c
있는 경우 모두 제거하고 추가합니다 c
". 중복이 없으면 currChar
아무것도 삭제되지 않으며, 중복이 있으면 중복 이전의 모든 문자가 한 번에 삭제됩니다. 이는 ${frontstr#*"$c"}$c
하나의 변수 확장을 사용하여 셸에서 수행됩니다 .
답변3
POSIX sh
인수 확산 연산자를 사용하여 printf
유틸리티를 한 번 호출하고 여러 번 호출합니다 [
.
string=abcbdbdsdfng
cur= n=0 longest=
while [ -n "$string" ]; do
c=${string%"${string#?}"}
new_cur=${cur#*"$c"}
if [ "$new_cur" = "$cur" ]; then
cur=$cur$c
string=${string#?}
l=${#cur}
if [ "$l" -gt "$n" ]; then
n=$l longest=$cur
fi
else
cur=$new_cur
fi
done
printf '"%s" (%d)\n' "$longest" "$n"
답변4
POSIX sh
구문과 유틸리티에 대한 단일 호출을 사용하여 sed
다음을 수행할 수 있습니다.
<input sed '
# clean-up hold space
x;s/.*//;x
# insert a running ">" cursor
s/^/>/
:start
/>$/! {
# pull the next character
s/>\(.\)/\1>/
# if what is left of > contains a duplicated character
/\(.\).*\1.*>/ {
# remove first char
s/^.//
b start
}
# does not contain a duplicated char. Is it longer than
# the currently selected one?
H; # append to hold space
g;s/\n/>/;s/[^>]/./g
# now the pattern space contains ...>....>... and we compare
# the number of .s in the first two sections
/^\([^>]*\)>\1[^>]/ {
# it is longer, store in hold space
g
s/.*\n//;s/>.*//
x
s/.*\n//
b start
}
# it is not longer
g
s/\n.*//;x;s/.*\n//
b start
}
g
# count the number of characters
s/./o/g
s/^/:|/
:1
s/|o\{10\}/x|/
t 1
s/$/9876543210/
s/\(.*:\)\(x*\)|.\{9\}\(.\).*/\3\1|\2/
y/x/o/
/o/b1
s/:.*//
G
s/\(.*\)\n\(.*\)/"\2" (\1)/
'
이는 입력에 문자가 없다고 가정할 때 입력의 각 줄에 대해 반복되는 문자가 없는 가장 긴 문자 시퀀스를 제공합니다 >
.