Cpp로 코드 깔끔하게 짜기 힘들다
문제
#include <unordered_map>
using namespace std;
unordered_map<int, int> S;
요런 코드에서 value가 0인 모든 엔트리를 제거하고 싶다면 어떻게 해야 할까?
실패의 기록
다음과 같은 코드를 짜다가 현타가 왔다.
for (auto &it: S) {
if (it.second == 0) {
S.erase(it);
continue;
}
}
S.erase(it) 하고나서 continue하면 다음 iteration으로 넘어가는건 use-after-free 아닌가, 그럼 S.erase(it++) 해야하나? 근데 거기서 continue하면 it++이후에 체크없이 continue하니까 0 entry가 두개 연속 있을때 두번째 엔트리는 체크하지 않는 버그가 생기잖아?
그거 피하려면 이렇게 해야하나?
for (auto &it: S) {
while(it.second == 0) {
S.erase(it++);
}
}
이러면 it가 이미 S.end()에 도달한 경우엔 빠져나와야 할텐데? 그럼 이렇게 해야하나?
for (auto &it: S) {
while(it != S.end() && it.second == 0) {
S.erase(it++);
}
if (it == S.end()) {
break;
}
}
해결?
AI에게 깔끔한 코드를 작성해보라고 하니 이런 코드를 준다.
for (auto it = S.begin(); it != S.end(); ) {
if (it->second == 0) {
it = S.erase(it);
} else {
++it;
}
}
흠… 확실히 iterator 복사가 일어나지도 않고, 깔끔해지긴 했는데, for range는 못쓴다는게 좀 아쉽다.
간만에 알고리즘 코딩을 AI 없이 하려고 해 보니 집중도 잘 안되고 코드도 깔끔하지 못하다.