Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 연결 리스트로 런 길이 인코딩(RLE) 구현하기

이번 튜토리얼에서는 연결 리스트(Linked List)를 활용해 런 길이 인코딩(Run Length Encoding, RLE)을 구현하는 C++ 프로그램을 살펴보겠습니다.

런 길이 인코딩(RLE)이란?

런 길이 인코딩은 연속해서 반복되는 데이터를 '값 + 반복 횟수' 형태로 치환하는 대표적인 무손실 압축 기법입니다. 이번 예제의 목표는 주어진 연결 리스트의 요소들을 이 방식으로 인코딩하는 것입니다.

예를 들어 연결 리스트의 요소가 "a->a->a->a->a"라면, 런 길이 인코딩을 적용한 결과는 "a → 5"가 됩니다. 즉, 문자 'a'가 5번 연속으로 나타난다는 의미입니다.

C++ 구현 예제

아래 코드는 노드 구조체 정의, 새 노드 생성, 노드 추가, 리스트 출력, 그리고 실제 인코딩을 수행하는 함수까지 전체 과정을 담고 있습니다. 입력 리스트가 "a → a → b → b → r → r"이라면 각 문자가 2번씩 반복되므로 최종적으로 "a 2 b 2 r 2"가 출력됩니다.

#include <bits/stdc++.h>
using namespace std;
// 연결 리스트 노드 구조체 정의
struct Node {
    char data;
    struct Node* next;
};
// 새 노드 생성
Node* newNode(char data){
    Node* temp = new Node;
    temp->data = data;
    temp->next = NULL;
    return temp;
}
// 리스트 끝에 노드 추가
void add_node(struct Node* head_ref, char new_data){
    struct Node* new_node = newNode(new_data);
    struct Node* last = head_ref;
    if (head_ref == NULL) {
        head_ref = new_node;
        return;
    }
    while (last->next != NULL)
        last = last->next;
    last->next = new_node;
    return;
}
// 연결 리스트 출력
void print_llist(Node* node){
    while (node != NULL) {
        cout << node->data << " ";
        node = node->next;
    }
}
// 주어진 리스트를 런 길이 인코딩
void llist_encode(Node* head){
    Node* p = head;
    Node* temp = newNode(p->data);
    char c = p->data;
    p = p->next;
    int count = 1;
    while (p != NULL) {
        char x = p->data;
        if (c == x)
            count++;
        else {
            if (count > 1) {
                if (count > 9)
                    add_node(temp, '0' + (count / 10));
                add_node(temp, '0' + (count % 10));
            }
            count = 1;
            add_node(temp, x);
            c = x;
        }
        p = p->next;
    }
    if (count != 0)
        add_node(temp, '0' + count);
    print_llist(temp);
}
int main(){
    Node* head = newNode('a');
    head->next = newNode('a');
    head->next->next = newNode('b');
    head->next->next->next = newNode('b');
    head->next->next->next->next = newNode('r');
    head->next->next->next->next->next = newNode('r');
    llist_encode(head);
    return 0;
}

코드 동작 원리

llist_encode() 함수는 리스트를 한 번만 순회하면서 현재 문자와 다음 문자를 비교합니다. 같은 문자가 이어지면 카운트를 1씩 증가시키고, 다른 문자가 등장하면 그동안 세었던 카운트를 임시 리스트에 추가한 뒤 기준 문자를 새로 바꿉니다. 특히 반복 횟수가 9를 초과할 경우 '0' + (count / 10)과 '0' + (count % 10)으로 자릿수를 나누어 두 개의 숫자 노드로 저장하기 때문에, 두 자리 수 반복 횟수도 올바르게 처리할 수 있다는 점이 특징입니다.

실행 결과

a 2 b 2 r 2

'a', 'b', 'r'이 각각 2번씩 연속 등장했기 때문에 위와 같은 결과가 출력됩니다. 이처럼 런 길이 인코딩은 반복 패턴이 많은 데이터에서 저장 공간을 크게 절약할 수 있는 효율적인 압축 방식입니다.