- 질문 게시판입니다.
Date | 19/10/03 22:00:24 |
Name | ![]() |
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
이 게시판에 등록된 kaestro님의 최근 게시물 |
원본 문제를 보지 않고 쓰는 답변이라 영 이상한 소리가 될지도 모르겠습니다만, 일단 아는 한에서 적어보겠습니다.
----------------------------------------------------------------------------
1. 일단 iterator를 사용할때 iterator를 수정하면 의도치 않은 동작을 하기 쉽습니다.
최대한 for문 내부에서는 대상을 변경하지 않도록 합시다.
변경이 필요하면 대상 자체의 iterator 대신 다른 변수를 사용해서 for문을 구현하는것이 좋습니다.
2. ... 더 보기
----------------------------------------------------------------------------
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같은 콘테이너의 오버헤드로 인한 시간초과가 날 수도 있고요.
가능하다면 문제도 같이 링크걸어주시면 더 자세히 알려드릴 수 있을거 같습니다.
----------------------------------------------------------------------------
1. 일단 iterator를 사용할때 iterator를 수정하면 의도치 않은 동작을 하기 쉽습니다.
최대한 for문 내부에서는 대상을 변경하지 않도록 합시다.
변경이 필요하면 대상 자체의 iterator 대신 다른 변수를 사용해서 for문을 구현하는것이 좋습니다.
2. c++에서 unordered_map 이 생각보다 성능면에서 장점이 별로 없습니다.
단순한 키에서는 ordered_map 보다 성능이 더 안나오는 경우도 많고요.
3. 문제를 보지 못해서 단언하지는 못하겠지만,
아무래도 시간 복잡도를 계산해 보면 unordered_map이건, ordered_map이건 시간을 초과하는 상황이 아닐까 싶습니다.
그렇지 않더라도 vector나 map같은 콘테이너의 오버헤드로 인한 시간초과가 날 수도 있고요.
가능하다면 문제도 같이 링크걸어주시면 더 자세히 알려드릴 수 있을거 같습니다.
아뇨, 몰랐던 이야기들이고 굉장히 도움이 많이 됐습니다. 감사합니다.
unordered_map이 ordered_map보다 단순한 키에서 성능이 안 나오는 경우에 성능이 안 나오는 경우가 많다면 아마 이것도 비슷한 경우일 수도 있겠네요.
질문 올리고서 답변들 받으면서 추가로 구현한 방법도 몇 가지 있었는데 이것도 시간초과가 발생하더라구요.
문제가 단순히 링크만 드리면 회원가입을 하지 않고 들어가 볼 수가 없는데, 회원가입을 하시는게 싫으실 경우 이메일을 쪽지로 보내주시면 제가 html 파일을 보내드리겠습니다.
일단 링크는 https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRJ8EKe48DFAUo 입니다.
unordered_map이 ordered_map보다 단순한 키에서 성능이 안 나오는 경우에 성능이 안 나오는 경우가 많다면 아마 이것도 비슷한 경우일 수도 있겠네요.
질문 올리고서 답변들 받으면서 추가로 구현한 방법도 몇 가지 있었는데 이것도 시간초과가 발생하더라구요.
문제가 단순히 링크만 드리면 회원가입을 하지 않고 들어가 볼 수가 없는데, 회원가입을 하시는게 싫으실 경우 이메일을 쪽지로 보내주시면 제가 html 파일을 보내드리겠습니다.
일단 링크는 https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRJ8EKe48DFAUo 입니다.
사실 그냥 맵사이즈 크게 잡고, offset잡으면 풀리는 문제고 실제로 돌아다니는 solution 보면 다 그렇게 풀긴 하는 것 같더라구요...
제가 요즘 stl 쓰는 연습하는 중이라 혹시 이렇게 풀 방법은 없을까하고 좀 뻘짓해보는 중인 거긴 해서 ㅎㅎ...
지금까지 답변주신거로도 도움이 많이 됐습니다. 일단 이번 하반기에 시험을 보게 된다면 이렇게 풀면 안될거라는 것 정도는 확실히 알아가는 것 같네요...
감사합니다
제가 요즘 stl 쓰는 연습하는 중이라 혹시 이렇게 풀 방법은 없을까하고 좀 뻘짓해보는 중인 거긴 해서 ㅎㅎ...
지금까지 답변주신거로도 도움이 많이 됐습니다. 일단 이번 하반기에 시험을 보게 된다면 이렇게 풀면 안될거라는 것 정도는 확실히 알아가는 것 같네요...
감사합니다
굳이 map을 써야 할 이유를 잘 모르겠는데... 굳이 이렇게 풀고 싶으시다면, 맵에 새로 들어가게 될 cell들을 저장할 vector를 하나 마련하시고 순회가 끝난 다음에 map에 한번에 insert하세요.
많은 분들이 말씀해주셔서 일단 그런식으로도 해결했는데 그것도 time limit 을 통과 못하더라구요
말씀하신대로 굳이 map을 써야하냐는 말을 다들 하셨는데, map을 안 쓰면 제한조건에 맞춰서 가능한 것보다 훨씬 큰 array 혹은 vector를 잡아서 음수로도 진행하는게 아니면 처음에 주어진 것보다 큰 영역까지 추가할 방법을 몰라서 이렇게 구성해봤습니다.
처음에 크기가 2by2로 주어진 상태에서 매 시간마다 계속해서 커질 수 있는 상태에서 map을 쓰거나, 그것보다 큰 arry를 잡은 다음 가운에서 시작하는 것 이외에 다른 방법이 있을까요?
말씀하신대로 굳이 map을 써야하냐는 말을 다들 하셨는데, map을 안 쓰면 제한조건에 맞춰서 가능한 것보다 훨씬 큰 array 혹은 vector를 잡아서 음수로도 진행하는게 아니면 처음에 주어진 것보다 큰 영역까지 추가할 방법을 몰라서 이렇게 구성해봤습니다.
처음에 크기가 2by2로 주어진 상태에서 매 시간마다 계속해서 커질 수 있는 상태에서 map을 쓰거나, 그것보다 큰 arry를 잡은 다음 가운에서 시작하는 것 이외에 다른 방법이 있을까요?
목록 |
|