- 질문 게시판입니다.
Date 19/10/03 22:00:24
Name   kaestro
Subject   c++ 에서 unordered map을 pair를 key로 사용할 때 순회
문제가 지도상에 상하좌우로 증식하는 세포가 주어질 때[맵의 크기 제한 없이] 일정 시간이 지난 후 살아있는 세포의 수를 세는 문제를 풀고 있는데,

솔루션에서는 문제 상에서 숫자 제약조건 때문에 나올 수 있는 최대보다 큰 배열을 이용해서 문제를 해결했는데, 저는 실제로 map 자료구조를 이용해서 문제를 풀어보고 싶어 그렇게 문제를 풀었습니다.

c++ map을 써서 돌아가는 코드는 만들었는데, 크기가 커지면 시간 제약 조건을 통과하지 못해서, 그럼 unordered map을 쓰면 되지 않을까? 하는 생각에 unordered_map으로 자료구조를 바꿨는데 지금 insert를 하고 나서 순회를 하면 문제가 생기더라구요.

아래 코드에서 simulation에서 iterator가 breeding을 하고 나면, 저장되어있는 simulation의 구조가 변형이 되면서 아직 순회해야하는 세포는 건너뛰거나, 아까전에 순회했던 세포를 재차 순회하는 문제가 발생하고 있습니다.

이 문제를 해결하려고 map을 따로 copy 뜨는 식으로 문제도 풀어봤는데, 이건 map을 copy하는게 오래 걸려서 그런지 기존의 map을 이용한 풀이보다 속도가 떨어지더라구요.

이런 경우에 unordered_map에 새로운 노드를 추가하면서, 아직 순회하지 않은 노드를 순회하고, 기존의 unordered_map을 카피하지 않는 방법이 있을까요?

감사합니다.

void simulate() {
    for (int i = 0; i < timeLimit; ++i) {
        for (myMap::iterator it = simulation.begin(); it != simulation.end();++it) {
          if (it->second.active == DEAD || it->second.lifetime == -1) continue;
          if (it->second.active == ACTIVE) {
                const ii& pos = it->first;
                const StemCell& sc = it->second;
                breed(pos, sc);
                it = simulation.find(pos);
            }
        }

        for (myMap::iterator it = simulation.begin(); it != simulation.end(); ++it) {
            it->second.increment();
        }
    }
}

void breed(const ii& pos, const StemCell& st) {
    for (int d = 0; d < direction.size(); ++d) {
        ii nextPos = { pos.first + direction[d].first, pos.second + direction[d].second };
        myMap::iterator it = simulation.find(nextPos);
      if (it == simulation.end()) {
            simulation[nextPos] = StemCell(-1, st.healthPoint);
        } else if (it->second.lifetime == -1){
          if (it->second.healthPoint < st.healthPoint) {
            it->second.healthPoint = st.healthPoint;
            }
        }
    }
}

ps. 전에 이런 질문 올렸을 때 코드 전문을 올려달라 하신 분이 계셨어서, 링크를 달아 둡니다.
(stl map 사용) https://github.com/kaestro/algorithms/blob/master/swexpert%20academy/5653.cpp
(stl unorderd_map 사용) https://github.com/kaestro/algorithms/blob/master/swexpert%20academy/5653_unordered.cpp



0


원본 문제를 보지 않고 쓰는 답변이라 영 이상한 소리가 될지도 모르겠습니다만, 일단 아는 한에서 적어보겠습니다.
----------------------------------------------------------------------------

1. 일단 iterator를 사용할때 iterator를 수정하면 의도치 않은 동작을 하기 쉽습니다.
최대한 for문 내부에서는 대상을 변경하지 않도록 합시다.
변경이 필요하면 대상 자체의 iterator 대신 다른 변수를 사용해서 for문을 구현하는것이 좋습니다.

2. ... 더 보기
원본 문제를 보지 않고 쓰는 답변이라 영 이상한 소리가 될지도 모르겠습니다만, 일단 아는 한에서 적어보겠습니다.
----------------------------------------------------------------------------

1. 일단 iterator를 사용할때 iterator를 수정하면 의도치 않은 동작을 하기 쉽습니다.
최대한 for문 내부에서는 대상을 변경하지 않도록 합시다.
변경이 필요하면 대상 자체의 iterator 대신 다른 변수를 사용해서 for문을 구현하는것이 좋습니다.

2. c++에서 unordered_map 이 생각보다 성능면에서 장점이 별로 없습니다.
단순한 키에서는 ordered_map 보다 성능이 더 안나오는 경우도 많고요.

3. 문제를 보지 못해서 단언하지는 못하겠지만,
아무래도 시간 복잡도를 계산해 보면 unordered_map이건, ordered_map이건 시간을 초과하는 상황이 아닐까 싶습니다.
그렇지 않더라도 vector나 map같은 콘테이너의 오버헤드로 인한 시간초과가 날 수도 있고요.
가능하다면 문제도 같이 링크걸어주시면 더 자세히 알려드릴 수 있을거 같습니다.
kaestro
아뇨, 몰랐던 이야기들이고 굉장히 도움이 많이 됐습니다. 감사합니다.
unordered_map이 ordered_map보다 단순한 키에서 성능이 안 나오는 경우에 성능이 안 나오는 경우가 많다면 아마 이것도 비슷한 경우일 수도 있겠네요.
질문 올리고서 답변들 받으면서 추가로 구현한 방법도 몇 가지 있었는데 이것도 시간초과가 발생하더라구요.
문제가 단순히 링크만 드리면 회원가입을 하지 않고 들어가 볼 수가 없는데, 회원가입을 하시는게 싫으실 경우 이메일을 쪽지로 보내주시면 제가 html 파일을 보내드리겠습니다.
일단 링크는 https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRJ8EKe48DFAUo 입니다.
아 sw expert academy였군요...
저도 계정이 있으니 다음에 시간이 되면 풀어보고 알려드리겠습니다 ㅎㅎ
kaestro
사실 그냥 맵사이즈 크게 잡고, offset잡으면 풀리는 문제고 실제로 돌아다니는 solution 보면 다 그렇게 풀긴 하는 것 같더라구요...
제가 요즘 stl 쓰는 연습하는 중이라 혹시 이렇게 풀 방법은 없을까하고 좀 뻘짓해보는 중인 거긴 해서 ㅎㅎ...
지금까지 답변주신거로도 도움이 많이 됐습니다. 일단 이번 하반기에 시험을 보게 된다면 이렇게 풀면 안될거라는 것 정도는 확실히 알아가는 것 같네요...
감사합니다
1
Azurespace
굳이 map을 써야 할 이유를 잘 모르겠는데... 굳이 이렇게 풀고 싶으시다면, 맵에 새로 들어가게 될 cell들을 저장할 vector를 하나 마련하시고 순회가 끝난 다음에 map에 한번에 insert하세요.
1
kaestro
많은 분들이 말씀해주셔서 일단 그런식으로도 해결했는데 그것도 time limit 을 통과 못하더라구요
말씀하신대로 굳이 map을 써야하냐는 말을 다들 하셨는데, map을 안 쓰면 제한조건에 맞춰서 가능한 것보다 훨씬 큰 array 혹은 vector를 잡아서 음수로도 진행하는게 아니면 처음에 주어진 것보다 큰 영역까지 추가할 방법을 몰라서 이렇게 구성해봤습니다.
처음에 크기가 2by2로 주어진 상태에서 매 시간마다 계속해서 커질 수 있는 상태에서 map을 쓰거나, 그것보다 큰 arry를 잡은 다음 가운에서 시작하는 것 이외에 다른 방법이 있을까요?
Azurespace
이 맵 제한을 없애고 싶으시다면... 저라면 일단 시간 1마다의 변화를 모두 에뮬레이션하려고 시도하지 않을 것 같습니다. 시간 순서대로 정렬되는 우선순위 큐를 활용해서 일종의 메시지 큐를 만들겠어요.
목록
번호 제목 이름 날짜 조회 추천
8660 IT/컴퓨터윈도우 보안 문의 7 흥차넷 20/01/22 5260 0
8655 IT/컴퓨터피씨가 절전모드 들어가면 깨지를 않습니다. 9 Zel 20/01/21 4471 0
8652 IT/컴퓨터(유튜브 프리미엄)돈을 준다는데 왜 받지를 못하니!! 4 [익명] 20/01/20 3989 0
8642 IT/컴퓨터Google Presentation 에 포함된 동영상을 다운로드 하는 방법 1 미스터주 20/01/17 4365 0
8631 IT/컴퓨터갤럭시탭 구입 질문 6 곰곰이 20/01/14 3542 0
8629 IT/컴퓨터버티컬 마우스를 살것입니다!! 14 Groot 20/01/14 4542 0
8622 IT/컴퓨터갤럭시 클럽이란 거 괜찮을까요? 4 쿠르드 20/01/12 4580 0
8619 IT/컴퓨터핸드폰 교체와 관련하여(주로 중고) 4 [익명] 20/01/11 3395 0
8606 IT/컴퓨터바탕화면 어디서 구하시나요 19 세나개 20/01/09 15922 0
8591 IT/컴퓨터[회사업무관련] E-BOOK 구현 홈페이지 만드는 빠른 방법? 4 루키루키 20/01/06 5251 0
8563 IT/컴퓨터노트북 CPU로 i5 10세대와 8세대 차이가 많이 날까요? 5 2월3일 19/12/31 17429 0
8534 IT/컴퓨터마이크 질문입니다. 10 [익명] 19/12/26 2935 0
8528 IT/컴퓨터엑셀/한셀 질문 5 OshiN 19/12/23 3225 0
8520 IT/컴퓨터아이패드 프로 3세대의 치명적인 단점을 최대한 적나라하게 알려주십시오. 13 Blackmore 19/12/21 5352 0
8518 IT/컴퓨터공유기 사용 후 토렌트 다운로드 속도가 제대로 안나옵니다. (공유기 설정관련 질문) 1 180611 19/12/21 7975 0
8515 IT/컴퓨터필기 가능한 윈도우 어플 추천 부탁드려요.. 5 grey 19/12/20 4700 0
8514 IT/컴퓨터이 노트북 어떨까요..?? 4 grey 19/12/20 3973 0
8513 IT/컴퓨터전자팩스에 대한 질문을 드리고 싶습니다. 1 불타는밀밭 19/12/20 3245 0
8511 IT/컴퓨터G8 쓰고 계시는분?? 8 Groot 19/12/19 4477 0
8504 IT/컴퓨터공유기 질문 드려요... 1 정중아 19/12/18 3980 0
8501 IT/컴퓨터MSSQL 데이터베이스 관련 질문입니다 8 거소 19/12/18 3578 0
8500 IT/컴퓨터유선 인터넷 속도와 공유기 성능 1 [익명] 19/12/18 3309 0
8496 IT/컴퓨터각종 싸이트의 아이디 비밀번호 등등을 텍스트 파일로 담아놓는 건 위험한가요? 34 [익명] 19/12/17 6040 0
8488 IT/컴퓨터맥북에서 동영상 보다 소리가 끊깁니다 9 토비 19/12/16 4066 0
8484 IT/컴퓨터초긴급) 동영상을 재생목록에 담아 플레이시 다음 파일로 넘어갈 때 약간의 음소거가 있는데 없애고 싶습니다. 1 소원의항구 19/12/16 3731 0
목록

+ : 최근 2시간내에 달린 댓글
+ : 최근 4시간내에 달린 댓글

댓글