"데이터베이스 테이블을 클래스 형태로 구현시 이슈" 글에서 잠시 언급했던 것 중에 '중복제거'와 관련된 알고리즘을 소개한다. 물론 자료구조나 알고리즘 수업을 들어본 사람이 있으면 쉽게 구현이 가능하다. 사실 현업에 오래있는 동안 이러한 로직을 잘 사용하지 않으면 기억이 잘 나지 않는다.
나 역시 그런 면이 있었는데, 그냥 혼자서 곰곰히 생각해 본 대로 구현해 보았다.
이전 글에서 실제로 예제를 들을 수 있었으면 좋겠다고 언급한 적이 있는데, 이번 예제에서는 테이터 베이스의 클래스를 예로 들진 않았다. 하지만 샘플 코드를 통해서 알 수 있는 것은 테이블을 자바 클래스로 매핑을 하였다면 필시 테이블의 PK에 해당하는 키를 하나의 properties로 표현하였을 것이다. 즉, 중복제거에 필요한 column을 표현한 것인데 이를 샘플예제의 array index 라고 생각하면 된다. 이를 통해서 응용을 하여 실제 업무에 사용해도 무방하리라 생각된다.
본 샘플예제에서 한 가지 개선할 점은 결과 배열의 크기를 미리 예측하기 힘들어 원본 배열과 동일한 크기를 할당한다는 것이다. 자바는 동적 배열을 지원함으로 크기를 미리 알 수 있다면 불필요한 메모리 크기를 사용하지 않아도 된다. 이에 대해서는 좋은 아이디어가 있으면 함께 해 주었으면 좋겠다.
그리고 참고적으로 실무에선 데이터베이스의 테이블을 클래스 매핑시켜 이러한 중복제거를 사용시에는 배열을 이용할 경우가 없을 것이다. 대부분 List 형태로의 Collection을 이용함으로 이러한 처리는 오히려 배열을 사용하는 것보다는 쉽게 구현이 가능할 뿐만 아니라 메모리 할당에 대해서도 고민할 필요가 없을 것이다.
자, 이제 실제로 테스트 코드를 살펴보자.
/**
* DuplicationRemoveTest.java
*/
package net.wiseant.test.algorithm;
import java.util.Random;
import junit.framework.TestCase;
/**
* @author Sang Hyup Lee
* @version 1.0
*
*/
public class DuplicationRemoveTest extends TestCase {
private Random random;
private int min = 1;
private int max = 10;
private static int ARRAY_LENGTH = 20;
private int getRandomNumber()
{
return random.nextInt((max - min) + 1) + min;
}
int[] array = new int[ARRAY_LENGTH];
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
random = new Random();
for ( int i=0; i < array.length; i++ ) {
array[i] = getRandomNumber();
System.out.println("array[" + i + "] : " + array[i]);
}
}
public void testDuplicationRemove() {
int[] duplicationRemoveArray = new int[ARRAY_LENGTH];
int index = 0;
System.out.println("============ PROCESS ============");
for ( int k=0; k < array.length; k++ ) {
if ( index == 0 ) {
duplicationRemoveArray[index] = array[k];
index++;
} else {
boolean isDuplication = false;
for ( int m=0; m < duplicationRemoveArray.length; m++ ) {
if ( array[k] == duplicationRemoveArray[m] ) {
isDuplication = true;
break;
}
}
if ( isDuplication ) {
System.out.println("Duplication number : " + array[k]);
} else {
duplicationRemoveArray[index] = array[k];
index++;
}
}
}
System.out.println("============ RESULT ============");
for ( int j=0; j < duplicationRemoveArray.length; j++ ) {
if ( duplicationRemoveArray[j] == 0 ) break;
System.out.println("duplicationRemoveArray[" + j + "] : " + duplicationRemoveArray[j]);
}
}
}
위의 소스 코드는 TDD 형태로 구현되어져 있다. TDD에 대해서는 다음에 기회가 있으면 언급을 하기로 하고 그냥 이렇게도 TDD를 사용할 수 있다는 것도 Tip 이라고 할 수 있겠다.
위의 소스 코드의 한 예를 살펴보면 다음과 같다.
array[0] : 2
array[1] : 3
array[2] : 2
array[3] : 2
array[4] : 1
array[5] : 2
array[6] : 8
array[7] : 7
array[8] : 9
array[9] : 4
array[10] : 1
array[11] : 3
array[12] : 1
array[13] : 3
array[14] : 1
array[15] : 4
array[16] : 7
array[17] : 1
array[18] : 8
array[19] : 9
============ PROCESS ============
Duplication number : 2
Duplication number : 2
Duplication number : 2
Duplication number : 1
Duplication number : 3
Duplication number : 1
Duplication number : 3
Duplication number : 1
Duplication number : 4
Duplication number : 7
Duplication number : 1
Duplication number : 8
Duplication number : 9
============ RESULT ============
duplicationRemoveArray[0] : 2
duplicationRemoveArray[1] : 3
duplicationRemoveArray[2] : 1
duplicationRemoveArray[3] : 8
duplicationRemoveArray[4] : 7
duplicationRemoveArray[5] : 9
duplicationRemoveArray[6] : 4
결과를 가만히 살펴보면 중복된 숫자를 디스플레이하고 최종 중복이 제거된 배열의 결과를 디스플레이 하고 있다. 실제로 동작하는 코드에서는 크기가 정해진 배열에 랜덤으로 1~10에 해당하는 숫자를 발생시켜 원본 배열 - array - 에 저장해 두고 이를 결과 배열 - duplicationRemoveArray - 에 중복이 제거된 숫자만을 저장한다.
로직은 그렇게 어려운 것이 아니니 더 이상의 설명은 필요가 없으리라 본다. 끝으로 실제업무에선 List와 같은 Collection 객체를 사용하게 될 경우가 많다고 했는데, 필요시에 이와 같이 테스트 후에 적용해 보는 것이 좋다는 생각이 든다.
댓글 없음:
댓글 쓰기