3 minute read

코드

#include <bits/stdc++.h>
#define ll long long
using namespace std;

// 노드 클래스를 정의합니다
class Node {
public:
    Node* prev; // 이전 노드를 가리키는 포인터
    Node* next; // 다음 노드를 가리키는 포인터
    char data;  // 노드가 저장하는 데이터(문자)

    // 생성자: 멤버 변수 초기화
    Node(char data = 0) : prev(nullptr), next(nullptr), data(data) {}
};

// 편집기 클래스를 정의합니다
class Editor {
public:
    Node* head; // 링크드 리스트의 더미 헤드 노드
    Node* cur;  // 현재 편집 위치를 나타내는 포인터

    // 생성자: 초기 상태를 설정합니다
    Editor() {
        head = new Node(); // 헤드 노드 생성
        cur = head;        // 초기 상태에서 현재 편집 위치를 헤드 노드로 설정
    }

    // 문자 삽입 함수: 현재 편집 위치에 문자를 삽입합니다
    void insert(char data) {
        Node* newNode = new Node(data); // 삽입할 새 노드 생성

        // 다음 세 가지 상황에 따라 새로운 노드를 삽입합니다.

        // 상황 1: 링크드 리스트가 비어있을 경우
        if (head->next == nullptr) {
            head->next = newNode; // 헤드 노드의 다음으로 새 노드 연결
            newNode->prev = head; // 새 노드의 이전 노드로 헤드 노드 설정
            cur = newNode;        // 현재 편집 위치를 새 노드로 설정
        }
        // 상황 2: 현재 위치가 링크드 리스트의 끝일 경우
        else if (cur->next == nullptr) {
            newNode->prev = cur; // 새 노드의 이전 노드로 현재 노드 설정
            cur->next = newNode; // 현재 노드의 다음 노드로 새 노드 설정
            cur = newNode;       // 현재 편집 위치를 새 노드로 설정
        }
        // 상황 3: 현재 위치가 중간 노드일 경우
        else if (cur->next != nullptr) {
            newNode->next = cur->next;         // 새 노드의 다음 노드로 연결
            cur->next->prev = newNode;         // 연결한 다음 노드의 이전 노드를 새 노드로 설정

            cur->next = newNode; // 현재 노드의 다음 노드로 새 노드 설정
            newNode->prev = cur; // 새 노드의 이전 노드로 현재 노드 설정

            cur = newNode;       // 현재 편집 위치를 새 노드로 설정
        }
    }
    
    // 커서를 왼쪽으로 이동하는 함수
    void left() {
        if (cur->prev != nullptr) { // 현재 위치가 헤드 노드가 아닌 경우
            cur = cur->prev;        // 현재 위치를 이전 노드로 변경
        }
    }

    // 커서를 오른쪽으로 이동하는 함수
    void right() {
        if (cur->next != nullptr) { // 현재 위치가 링크드 리스트의 끝이 아닌 경우
            cur = cur->next;        // 현재 위치를 다음 노드로 변경
        }
    }

    // 현재 위치의 문자를 삭제하는 함수
    void del() {
        if (cur != head) { // 현재 위치가 헤드 노드가 아닌 경우
            cur->prev->next = cur->next; // 이전 노드를 다음 노드로 연결

            // 삭제할 노드가 마지막 노드가 아닌 경우
            if (cur->next != nullptr) {
                cur->next->prev = cur->prev; // 다음 노드의 이전 노드를 변경
            }

            Node* temp = cur; // 현재 노드의 포인터를 임시로 저장
            cur = cur->prev;  // 현재 위치를 이전 노드로 변경
            delete temp;      // 임시로 저장한 노드를 삭제
        }
    }
    
    // 최종 편집된 텍스트를 출력하는 함수
    void print() {
        Node* current = head->next; // 출력할 첫 번째 노드 참조
        // 노드를 차례대로 방문하며 데이터 출력
        while (current != nullptr) {
            cout << current->data;
            current = current->next;
        }
    }
};

int main(void) {
    // 알고리즘 수행 시간을 빠르게 하기 위해 입출력 속도 향상 설정
    ios::sync_with_stdio(NULL);
    cin.tie(NULL);

    string s;           // 초기 텍스트 상태
    int commandNum;     // 수행할 명령어의 개수
    cin >> s >> commandNum;      // 사용자로부터 초기 데이터와 명령어 개수를 입력받음

    Editor editor;      // 편집기 객체를 생성 및 초기상태 설정

    // 초기 텍스트 데이터를 편집기에 입력
    for (int i = 0; i < s.size(); i++) {
        editor.insert(s[i]);
    }

    // 각 명령어를 처리
    for (int i = 1; i <= commandNum; i++) {
        char command;
        cin >> command;         // 명령어를 입력받음

        // 명령어 종류에 따라 적절한 편집기 함수를 호출
        if (command == 'P') {
            char data;
            cin >> data;         // 삽입할 문자를 입력받음
            editor.insert(data); // 문자 삽입
        }
        else if (command == 'L') {
            editor.left();       // 커서 왼쪽 이동
        }
        else if (command == 'D') {
            editor.right();      // 커서 오른쪽 이동
        }
        else if (command == 'B') {
            editor.del();        // 현재 위치의 문자 삭제
        }
    }

    // 최종 편집 결과를 출력
    editor.print();

    return 0;
}

Leave a comment