- 질문 게시판입니다.
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마다의 변화를 모두 에뮬레이션하려고 시도하지 않을 것 같습니다. 시간 순서대로 정렬되는 우선순위 큐를 활용해서 일종의 메시지 큐를 만들겠어요.
목록
번호 제목 이름 날짜 조회 추천
3682 법률법 조항 부를 때 어떻게...? 15 먹이 17/11/14 5352 0
306 게임[LOL] 북미섭 하시는 분 계신가요? 3 하울 15/09/20 5352 0
13304 법률이런것도 횡령, 사문서 위조에 해당할까요? 윗선에 보고를 해야할까요? 16 [익명] 22/04/28 5351 0
12990 여행혼자서 갈만한 여행지가 있을까요?? 21 dongri 22/02/16 5351 0
12871 진로이직 관련 조언 부탁드립니다. 20 [익명] 22/01/22 5351 0
10260 의료/건강멍 빨리 빼는 방법 22 다람쥐 20/10/13 5351 0
9864 기타후진 중 접촉사고 문의드립니다 10 All is well 20/07/31 5351 0
5918 경제남편 명의 전세계약 종료후 아내 명의 전세계약시 보증금이 증여가 되나요? 3 [익명] 18/11/19 5351 0
4873 의료/건강왼쪽 어깨가 아프면 어느 병원엘 가는게 좋을까요? 2 18/06/22 5351 0
3742 IT/컴퓨터학식 게임컴퓨터 견적상담좀부탁드립니다 23 학식먹는사람 17/11/25 5351 0
2558 의료/건강24시간 수유는 임신 가능성을 크게 낮춘다. 11 에밀 17/03/26 5351 0
14104 IT/컴퓨터영상 편집용 피씨 견적 문의드립니다. 7 메존일각 22/11/08 5350 0
143 체육/스포츠K리그 가끔 보는 라이트 팬인데요. 4 솔지은 15/07/06 5350 0
12501 의료/건강안면마비 한방치료 필요할까요? 4 사과농장 21/11/01 5349 0
11935 IT/컴퓨터프로그래머 계층, 프로그램의 CPU점유율이 너무 낮습니다 40 매뉴물있뉴 21/07/23 5349 0
8150 체육/스포츠등산 갈때 옷 뭐입고 가나요? 12 헌혈빌런 19/10/30 5349 0
6920 과학천문or물리 바보 질문 26 우주견공 19/04/09 5349 1
5328 진로공무원으로 이직이 맞는걸까요 13 [익명] 18/08/26 5349 0
3235 여행양가 부모님 모시고 가는 제주도 여행지 추천 부탁드립니다. 6 캠팔이 17/08/20 5349 0
13344 기타자전거 구매 팁이 있을까요? 19 moqq 22/05/08 5348 0
13199 IT/컴퓨터SNS 플랫폼 프로토타입 개발을 해보고 싶습니다. 10 SCV 22/04/01 5348 0
13760 가정/육아신축아파트 입주전, 이것 만은 해야한다 24 물냉과비냉사이 22/08/16 5347 0
13403 문화/예술간송미술관 관람 시간 어느정도 잡아야 할까요? 8 even&odds 22/05/24 5347 0
12827 기타와인 추천 부탁드립니다. 14 의미있는삶 22/01/14 5347 0
10457 기타직장에서 다들 가면 쓰시나요?? 16 [익명] 20/11/16 5347 0
목록

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

댓글