한양과학기술고등학교

에듀테크 프로젝트 대시보드

버로우즈-휠러 변환 (BWT)

버로우즈-휠러 변환 (BWT)

문자열을 더 짧게 만들지 않으면서 순서만 뒤섞는데, 그 결과 같은 글자들이 옆으로 주르륵 뭉친다. 뭉친 데이터는 압축이 훨씬 잘 된다. 게다가 이 변환은 완벽하게 되돌릴 수 있다. bzip2 압축과 DNA 검색 엔진(FM-index)의 심장.

아이디어 — 원문의 모든 회전(rotation)을 만들어 사전순으로 정렬한 뒤, 각 줄의 마지막 글자만 뽑아 이어 붙인다. 정렬을 하면 비슷한 뒷문맥(suffix)을 가진 줄들이 이웃하게 되고, 그 앞 글자(=마지막 열)도 서로 비슷해진다 → 같은 글자가 연속으로 나온다.

1. 눈으로 보기 — 정변환

문자열 끝에 $(다른 어떤 글자보다 작은 종료 기호)를 붙인다. 「회전 생성」으로 n개의 회전을 만들고, 「정렬」로 사전순 정렬한 뒤, 마지막 열(보라색)을 읽으면 그게 BWT 결과다.

마지막 열 = BWT 출력

문자열 길이 n
7
원문 위치 (origin row)
–
최장 연속 구간(run)
–
「회전 생성」을 눌러 시작하세요.
첫 열 F (정렬된 글자) 마지막 열 L = BWT 원문이 있는 줄($로 끝나는 줄)

2. 왜 글자가 뭉칠까?

영어에서 he라는 글자쌍을 생각해 보자. 문장 곳곳의 "he ..."로 시작하는 회전들은 정렬 후 한곳에 모인다. 그 줄들의 마지막 글자는 원문에서 h 바로 앞에 오던 글자인데, 영어에서는 t(→ the)가 압도적으로 많다. 그래서 마지막 열에 ttttt...가 줄줄이 생긴다.

BWT 자체는 압축이 아니다. 길이가 그대로다. 하지만 뭉친 데이터는 MTF(Move-To-Front) + RLE(연속 길이 부호화) + 허프만/산술 부호화를 거치면 크게 줄어든다. 이게 bzip2의 파이프라인이다. → 허프만 코딩, LZ77과 비교해 보자.

3. 어떻게 되돌릴까? — LF 매핑

놀라운 점: 우리가 저장한 건 마지막 열 L과 원문 줄 번호뿐인데도 원문을 완벽히 복원한다. 열쇠는 두 가지 사실이다.

이 성질로 $에서 시작해 F↔L을 번갈아 따라가면 원문이 거꾸로 하나씩 튀어나온다.

복원된 원문 (뒤에서부터 채워짐)

정변환을 먼저 완료한 뒤 「한 글자 복원」을 누르세요.

4. 코드

# 정변환: 모든 회전을 정렬해 마지막 글자를 모은다
def bwt(s: str) -> str:
    s = s + "$"                          # 종료 기호(가장 작은 문자)
    rots = [s[i:] + s[:i] for i in range(len(s))]
    rots.sort()
    return "".join(r[-1] for r in rots)

# 역변환: LF 매핑으로 원문을 거꾸로 복원
def ibwt(L: str) -> str:
    n = len(L)
    # 각 L[i]가 F에서 몇 번째 줄로 가는지 계산 (안정 정렬)
    idx = sorted(range(n), key=lambda i: (L[i], i))
    row = L.index("$")                     # $로 끝나는 줄 = 원문 줄
    out = []
    for _ in range(n):
        row = idx[row]
        out.append(L[row])
    return "".join(out)[::-1].rstrip("$")

assert ibwt(bwt("banana")) == "banana"   # bwt("banana") == "annb$aa"

※ 실제 구현은 회전 문자열을 실제로 만들지 않고 접미사 배열(suffix array)을 O(n) 또는 O(n log n)으로 만들어 L[i] = s[SA[i]-1]로 계산한다. → 기수 정렬이 접미사 배열 구축에 쓰인다.

5. 어디에 쓰일까

분야쓰임
bzip2블록 단위 BWT → MTF → RLE → 허프만. gzip보다 느리지만 압축률이 높다
생물정보학 (BWA, Bowtie)참조 유전체를 BWT로 색인(FM-index)해 수십억 개 DNA 조각을 초고속 정렬
전문 검색 (FM-index)원문을 저장하지 않고도 부분 문자열의 등장 횟수·위치를 O(패턴 길이)에 질의
한 줄 요약 — BWT는 "정렬"이라는 도구로 데이터의 지역적 반복 구조를 표면으로 끌어올린다. 압축기는 그 뭉침을 먹고, 검색 엔진은 그 정렬된 구조를 색인으로 쓴다. 그리고 전부 되돌릴 수 있다.