Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2-oesnuj #8

Merged
merged 2 commits into from
Apr 2, 2024
Merged

2-oesnuj #8

merged 2 commits into from
Apr 2, 2024

Conversation

oesnuj
Copy link
Member

@oesnuj oesnuj commented Mar 29, 2024

🔗 문제 링크

https://www.acmicpc.net/problem/1406

✔️ 소요된 시간

45분

✨ 수도 코드

키보드 입력, 삭제, 커서의 동작을 코드로 표현하는 문제였습니다.
커서의 움직임으로 중간의 데이터를 자주 삽입, 삭제를 하므로 list(양방향 연결리스트)나 vector를 사용하면 효율적일 것 같다고 생각했습니다.
연결리스트 STL을 써본적이 없어 이참에 해보자고 풀어봤습니다.
개인적으로 설명하기 힘든 문제였어요...

풀이과정

  1. 문자열을 입력받고 구성하는 한 문자씩 양방향 연결리스트에 삽입

  2. cursor = li.end(); 로 커서(iterator)의 시작점을 두었다.
    li.end()는 현재 연결리스트의 마지막 요소의 다음위치를 가르킵니다.
    cursor는 iterator로 요소의 위치를 가르키는 변수명입니다.

  3. 입력받는 명령어에 따른 처리를 나눈다.

  • L : 커서가 맨 앞이 아닌 경우에만 좌측으로 iterator를 한칸 옮긴다 -> it--;
  • D : 커서가 맨 뒤가 아닌 경우에만 우측으로 iterator를 한칸 옮긴다 -> it++;
  • B : 커서가 맨 앞이 아닌경우에는 cursor가 가리키는 앞의 문자를 지워야함으로 cursor를 하나 줄여 그 위치의 값을 erarse한다. 그 후 지운 다음 요소의 위치를 cursor로 두어 제자리로 돌린다.
    여기서 list의 erase함수로 원소를 지우면 지워진 원소 다음 원소의 iterator가 반환된다. 이 반환 값을 다시 cursor로 하여 커서를 제자리로 돌린다.
  • P : 삽입할 문자를 추가로 하나 더 입력받고 li.insert()를 사용해 현재 커서위치 앞에 문자를 삽입한다.
    li.insert(cursor, c) cursor의 앞의 위치에 c를 삽입한다. cursor는 변하지 않는다.

삽입, 삭제 구현할때 cursor(iterator)의 위치때문에 정신없었는데
핵심은 지우고 삽입해도 커서의 위치는 변하지 않는다는 점인 것 같네요.

예시

image

📑코드

#include <iostream>
#include <list>
using namespace std;
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    list <char> li; //양방향 연결리스트 선언
    string str;
    cin >> str;
    for (auto c : str) //한 문자씩 연결리스트에 넣기
        li.push_back(c);

    list<char>::iterator cursor = li.end();
    int t;
    cin >> t;
    while(t--)
    {
        char input;
        cin >> input;
        if (input == 'L')
        {
            if (cursor != li.begin())
                cursor--;
        }
        else if (input == 'D')
        {
            if (cursor != li.end())
                cursor++;
        }
        else if (input == 'B')
        {
            if (cursor != li.begin())
            {
                cursor--;
                cursor = li.erase(cursor);
            }   
        }
        else if (input == 'P')
        {
            char insertChar;
            cin >> insertChar;
            li.insert(cursor, insertChar);
        }
    }
    
    for (auto c : li)
        cout << c;
    return 0;
}

📚 새롭게 알게된 내용

양방향 연결리스트를 STL로 처음 사용해봐서 문법을 알아본다고 오래 걸렸습니다.
컨테이너를 다룰때 자주 쓰는 iterator(반복자)를 아직 능숙하게 사용하지 못하겠습니다. 많이 사용해보면서 익숙해지는 시간을 가져야 할 것 같네요!!
찾아보니 iterator가 C++만의 문법이 아니고 거의 대부분의 언어에 있다는 사실도 새로 알게되었네요.

Copy link
Collaborator

@suhyun113 suhyun113 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c++언어를 현재 배우면서 vector를 사용해보면서 느꼈지만, 정말 편리한 것 같았고 살짝 어려웠지만 이 코드에서 보게 되니 뭔가 반가웠어요.

저도 연결리스트 STL이라는 것을 본 적이 없기 때문에 이 코드를 이해하기 어려울 것 같아 살짝 두려웠는데, 문제를 읽어보니 준서님 처럼 cursor의 위치 때문에 정신이 없었고 cursor를 이동하는 조건 중 B가 가장 이해하기 힘들었습니다.
그런데, 준서님이 제시해주신 예시를 보고 입력값에 대해 차례대로 어떤 일이 일어나는지 cursor의 위치가 변하는 모습을 시각화해주셔서 이 예시를 보고 이 문제가 원하는 것에 대해 제대로 이해할 수 있었습니다!
또한 c++에서 list라는 헤더는 사용해본 적이 없었는데, list 구현도 가능하다는 것을 알게되었습니다. 직관적으로 코드를 알아보기 쉬워 이해하기 쉬웠습니다. 좋은 코드 잘 보고 갑니다!
PR작성하신다고 수고 많으셨어요~

Copy link
Collaborator

@pu2rile pu2rile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 저는 c++를 다뤄 본 적이 없어서 stl이라는 것을 이번 준서 님 PR로 처음 알게 되었는데 정말 편리한 라이브러리네요!! 블로그를 찾아보며 개념을 익히느라 코드 해석이 까다로웠지만 덕분에 새로운 것들 알아가요! 저도 여름 방학쯤 c++ 공부해 봐야겠습니다 ㅎㅎ 수고하셨어요!~

}
else if (input == 'D')
{
if (it != li.end())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

커서의 시작점을 두는 법을 새롭게 알게 되었네요!

@Ghdrn1399
Copy link
Contributor

C++ 언어를 사용 해 본적이 없었는데 준서님 덕분에 키보드 입력, 삭제, 커서의 동작을 코드로 표현하는 법을 알게 되었고
저도 더욱 공부 해야겠네요^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants