기본 콘텐츠로 건너뛰기

라벨이 비교인 게시물 표시

[알고리즘] 두 Graph 비교

 브랜치가 포함된 두 배관 라인을 비교하는 방법입니다. 아래와 같이 두 배관 라인이 존재할때 바뀐 부분을 찾는 로직입니다. 이 두 라인을 비교하기 위해 문자열 diff 알고리즘을 적용할 수 있습니다. 먼저 라인을 구성하는 항목들을 코드화 시킵니다. 두 라인을 문자열로 표현하면 $OLD = PRPTPRPBPOPRP$ $NEW = PRPRPBPOPRPTP$ 가 됩니다. 이제 배관 라인을 두 문자열로 만들었으니 문자열 diff 알고리즘을 적용시킬 차례입니다. LCS(Longest Common Subsequence)를 이용하여 두 문자열을 비교합니다. LCS는 다음 식으로 표현됩니다. $$LCS(X_i,Y_j) = \begin{eqnarray} \left\{ \begin{aligned} &0 && if\text{ }i = 0\text{ }or\text{ }j=0\\ &LCS(X_{i-1},Y_{j-1})+1 && if\text{ }X_i=Y_j\\&max(LCS(X_i,Y_{j-1}),LCS(X_{i-1},Y_j)) && if\text{ }X_i \neq Y_j \end{aligned} \right. \end{eqnarray}$$ $X,Y$는 비교할 문자열이고 $i,j$는 문자열의 인덱스입니다. 위 식을 이해하기 쉽게 2차원 배열로 나타내면 아래와 같습니다. 가장 큰 숫자인 11이 공통 부분 수열의 길이가 됩니다. 1에서 11까지 비용($Cost\text{ }=\text{ }i+j$)이 가장 작은 위치의 숫자를 선택하여 그 위치의 문자를 연결하면 공통 부분 수열이 됩니다.(공통 부분 수열은 하나가 아니라 여러개가 나타날 수 있습니다.) 공통 부분 수열은 $PRP\text{ }RPBPOPRP$(동그라미 친 부분)이며 변경이 일어나지 않은 부분입니다. 해석을 해보면 $OLD$에서 가운데 $TP$가 삭제되고 $NEW$에서 맨 끝에 $TP$가 추가되었습니다. 두 라인에서 브랜치가 변동이 없는 경우에는 두...

비교하는 정수 값으로 unsigned type을 쓰지 말자.

예전 프로젝트에서 큰 낭패를 보았는데, 흔히 우리가 for문을 아래와 같이 사용하게 되는데 for(int i = 0;i < max;++i) 예전 프로젝트의 일부분의 코드가 아래와 같이 되어있었습니다. for(size_t i = 0;i < max;++i) max의 값은 계산되어지는데 일반적으로 위의 코드는 아무런 문제가 없이 수행되었는데 max의 값이 음수가 될때에는 문제가 발생하게 됩니다. for(size_t i = 0;i < -1;++i) { printf("ddd"); } 위의 코드에서 print 함수가 호출되지 않을것 같지만 size_t가 가질수 있는 최대값만큼 호출됩니다. 컴파일러에서 size_t 타입과 비교를 위해 -1을 size_t타입으로 변환을 시켜버립니다. 그래서 우리가 원치 않는 결과가 발생하게 됩니다. 또한 아래의 코드도 위험합니다. 무한 루프를 돌게 됩니다. for(size_t i = 100;i >= 0;--i) { printf("ddd"); }