정의

갭 버퍼(Gap Buffer)는 동적 배열의 한 형태로, 특정 위치 근처에서 삽입 및 삭제 작업을 효율적으로 수행할 수 있도록 설계된 자료 구조이다. 주로 텍스트 편집기에서 사용되며, 커서 주변에서 주로 변경이 발생하는 특성을 반영한다.

구조 및 동작 원리

  • 텍스트는 두 개의 연속된 세그먼트로 저장되며, 그 사이에 빈 공간(gap) 이 존재한다.
  • 커서 이동 시 갭을 이동시키는 방식으로 동작하며, 필요할 때만 텍스트를 복사하여 성능을 최적화한다.
  • 삽입 시 첫 번째 세그먼트 끝에 새 텍스트를 추가하고, 삭제 시 해당 부분을 지운다.

특징

장점

  • 두 개의 문자열만으로 표현되므로 공간 효율성이 높음
  • 빠른 검색 및 출력 가능
  • 일반적인 편집 작업에서는 효율적

단점

  • 커서가 멀리 이동하면 많은 텍스트를 복사해야 하는 비효율성 발생
  • 갭이 가득 차면 새로운 갭을 만들어야 하며, 이 과정에서 전체 텍스트 복사가 필요할 수도 있음

예시

Kotlin 코드를 예시로 갭 버퍼를 구현해보겠습니다.

class GapBuffer(private val size: Int) {
    private val buffer = CharArray(size) { ' ' }  // 전체 버퍼 (갭 포함)
    private var gapStart = 0  // 갭의 시작 위치
    private var gapEnd = size / 2  // 갭의 끝 위치
 
    fun insert(text: String) {
        for (c in text) {
            if (gapStart == gapEnd) expandGap()  // 갭이 다 차면 확장
            buffer[gapStart++] = c  // 문자를 갭에 추가
        }
    }
 
    fun delete(count: Int) {
        gapStart = maxOf(0, gapStart - count)  // 갭을 앞으로 확장 (삭제)
    }
 
    fun moveCursor(position: Int) {
        if (position < gapStart) {  // 왼쪽으로 이동
            while (gapStart > position) {
                buffer[--gapEnd] = buffer[--gapStart]  // 문자 오른쪽으로 이동
            }
        } else {  // 오른쪽으로 이동
            while (gapEnd < position) {
                buffer[gapStart++] = buffer[gapEnd++]  // 문자 왼쪽으로 이동
            }
        }
    }
 
    private fun expandGap() {
        // 단순 예제: 갭 크기를 2배로 늘림 (실제 구현에서는 효율적으로 처리)
        val newGapEnd = minOf(buffer.size, gapEnd + 5)
        for (i in gapEnd until newGapEnd) buffer[i] = ' '
        gapEnd = newGapEnd
    }
 
    fun getText(): String {
        return (buffer.copyOfRange(0, gapStart) + buffer.copyOfRange(gapEnd, buffer.size))
            .joinToString("")
    }
}
 
 
// 사용 예제
fun main() {
    val gapBuffer = GapBuffer(20)
 
    gapBuffer.insert("Hello")
    println(gapBuffer.getText())  // Hello
 
    gapBuffer.moveCursor(2)  // "l" 앞(2번째 위치)로 이동
    gapBuffer.insert("X")
    println(gapBuffer.getText())  // HeXllo
 
    gapBuffer.delete(1)  // "X" 삭제
    println(gapBuffer.getText())  // Hello
 
    gapBuffer.moveCursor(5)  // "o" 뒤로 이동
    gapBuffer.insert(" World!")
    println(gapBuffer.getText())  // Hello World!
}
# 실행 결과
Hello
HeXllo
Hello
Hello World!

참고 문서