서론
보통 LeetCode 문제를 풀 때 저는 연습장이나 로컬 에디터를 사용하지 않고 문제 페이지의 코드 편집기에서 직접 코드를 작성합니다.
이러한 방식으로 문제를 푸는 경우 유료 기능을 사용하지 않으면 예상치 못한 버그가 발생할 수 있으며, 이를 찾는 데 많은 시간이 소요됩니다.
이 글에서는 과거에 경험한 문제들을 정리하고자 합니다.
사례 1
오랜 시간 동안 문제가 어디에 있는지 찾지 못했습니다. for 루프 뒤에 어떤 문장을 추가하더라도 오류가 발생했습니다. 결국 Visual Studio에서 실행해 보았을 때야 문제가 드러났습니다.
오류 원인: C++ 주석 끝에 있는 역슬래시(\)는 다음 줄까지 주석 처리를 연결시킵니다! 해결 방법: 주석 끝에 역슬래시를 사용하지 마세요(의도적인 경우 제외) 요약: 때때로 간단한 기초 지식이 갑작스럽게 큰 장애물이 될 수 있습니다. 하지만 이 문제는 로컬 컴파일러에서 코드를 작성할 경우 쉽게 발견할 수 있습니다(문자 색상이 녹색으로 변경되기 때문). 반면 LeetCode 인터페이스에서는 이러한 시각적 표시가 제공되지 않습니다.사례 2
오류 코드:
Line 1584: rapidjson::SizeType rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>>::Size() const \[Encoding = rapidjson::UTF8<char>, Allocator = rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>\]: Assertion `IsArray()' failed. (document.h)
오류 원인: 테스트 케이스 입력 형식이 잘못되었습니다!(현재 테스트 케이스는 제가 직접 입력한 것입니다) 해결 방법: 테스트 케이스 실행 요약:테스트 케이스를 입력할 때는 신중해야 합니다.
이처럼 행 번호가 매우 큰 오류는 일반적인 구문 오류가 아닌 경우가 많으므로, 다른 부분에 문제가 없는지 검토해야 합니다.
이 오류를 찾느라 오류 코드를 거의 외울 정도였습니다...
사례 3
코드:
class DisjointSet{
private:
vector<int> rank;
vector<int> root;
vector<int> groupCount;
int totalNodes;
public:
DisjointSet(int size){
for(int idx =0;idx<size;++idx){
root.push_back(idx);
rank.push_back(1);
}
groupCount.resize(size,1);
totalNodes = size;
}
int findRoot(int node){//경로 압축
int rootNode = root[node];
if(rootNode==node) return rootNode;
while(rootNode!=root[rootNode]){
rootNode = root[rootNode];
}
if(rootNode!=root[node])
root[node]=rootNode;
return rootNode;
}
int mergeSets(int x,int y){ //반환 값은 요구 사항에 맞추어 템플릿 수정
int rootX = findRoot(x);
int rootY = findRoot(y);
if(rootX!=rootY){
if(rank[rootX]>rank[rootY]){ //랭크 기반 병합
root[rootY]=rootX;
groupCount[rootX]+=groupCount[rootY];
}else if(rank[rootX]<rank[rootY]){
root[rootX]=rootY;
groupCount[rootY]+=groupCount[rootX];
}else{
root[rootX]=rootY;
rank[rootY]++;
groupCount[rootY]+=groupCount[rootX];
}
return 1;
}
return 0;
}
};
struct Connection{
int source,destination,cost;
Connection(int src,int dest ,int cost):source(src),destination(dest),cost(cost){}
};
class Solution {
public:
int minimumCostToConnect(vector<vector<int>>& coordinates) {
vector<Connection> connections;
int nodes = coordinates.size();
DisjointSet ds(coordinates.size());
for(int idx =0;idx<coordinates.size();++idx){
for(int jdx =idx+1;jdx<coordinates.size();++jdx){
int distance = abs(coordinates[idx][0]-coordinates[jdx][0])+abs(coordinates[idx][1]-coordinates[jdx][1]);
connections.emplace_back(idx,jdx,distance);
connections.emplace_back(jdx,idx,distance);
}
}
sort(connections.begin(),connections.end(),[&](Connection a,Connection b){
return a.cost<b.cost;
});
int totalLength=0,count=1;
for(auto& conn:connections){
if(ds.mergeSets(conn.source,conn.destination)){
totalLength += conn.cost;
count++;
if(count==nodes) return totalLength;
}
cout<<conn.cost<<endl;
}
return 0;
}
};
그런 다음 다음과 같은 오류가 발생했습니다:
오류 원인:
프로그램에 cout 문장을 추가했더니 일부 출력이 가능하다는 것을 확인할 수 있었으며, 이는 프로그램이 컴파일 단계에서는 문제가 없다는 의미입니다.
코드를 Visual Studio로 옮겨 실행했을 때 벡터 인덱스 범위 초과 오류가 발생했습니다. 여러 번 코드를 검토한 결과 문제를 발견할 수 있었습니다:
매개변수 순서가 잘못되었습니다. 원래는 idx, jdx, distance여야 했습니다. 잘못된 매개변수로 인해 disjoint set 클래스 내부에서 벡터 인덱스 범위를 벗어나게 되었습니다.
(수정 후에도 여전히 같은 오류가 발생하여 오랜 시간을 찾다 보니 struct Connection의 매개변수 source가 source로 오타가 나 있었음...)
해결 방법:
인덱스 범위 초과의 원인을 찾아 코드를 수정하세요.
사례 4
코드:
class Solution {
public:
vector<int> arrayPlusNumber(vector<int>& digits, int number) {
vector<int> numVector;
do{
numVector.insert(numVector.begin(),number%10);
number = number/10;
}while(number); //K==0인 경우를 고려하여 do while 사용
int pos =1;
vector<int>result;
int carry = 0;
while((digits.size()-pos>=0)&&(numVector.size()-pos>=0)){
carry+=digits[digits.size()-pos]+numVector[numVector.size()-pos];
result.insert(result.begin(),carry%10);
carry/=10;
pos++;
}
while(digits.size()>=pos){
carry+=digits[digits.size()-pos];
result.insert(result.begin(),carry%10);
carry/=10;
pos++;
}
while(numVector.size()>=pos){
carry+=numVector[numVector.size()-pos];
result.insert(result.begin(),carry%10);
carry/=10;
pos++;
}
if(carry)
result.insert(result.begin(),carry);
return result;
}
};
오류 원인:
수차례 디버깅을 거쳐 문제를 최종적으로 발견했습니다:
numVector.size()=2, pos=3일 때 numVector.size()-pos는 음수가 아닌 매우 크고 이상한 숫자가 됩니다.
이러한 현상이 발생하는 이유는 vector.size()가 부호 없는 정수형이기 때문입니다.
해결 방법:
이와 같이 작성하면 됩니다.
요약:
프로그래밍 언어를 배울 때는 기초를 탄탄히 다져야 합니다!