IntArrayBag 클래스
2025. 4. 18. 00:20ㆍ자료구조
코드 설명
/******************************************************************************
* IntArrayBag 클래스는 int 숫자들의 컬렉션(가방)을 나타냅니다.
* 동일한 숫자가 여러 번 포함될 수 있습니다.
*
* @note
* (1) 이 가방의 용량은 생성 후 변경이 가능하지만,
* 최대 용량은 머신의 사용 가능한 메모리에 의해 제한됩니다.
* 생성자, addItem, clone, union 등의 메서드는 메모리가 부족하면
* OutOfMemoryError를 발생시킬 수 있습니다.
* <p>
* (2) 가방의 최대 용량은 정수 최대값인 2,147,483,647 (Integer.MAX_VALUE)를 초과할 수 없습니다.
* 이를 초과하려 할 경우 산술 오버플로우로 인해 실패합니다.
* <p>
* (3) 이 클래스의 알고리즘은 느린 선형 방식이기 때문에, 큰 데이터셋에서는 성능이 저조할 수 있습니다.
*
******************************************************************************/
public class IntArrayBag implements Cloneable
{
// IntArrayBag 클래스의 불변식 (Invariant):
// 1. 가방에 있는 요소 수는 manyItems 변수에 저장되며, 이 값은 data.length를 넘지 않습니다.
// 2. 가방이 비어 있을 때는 data 배열의 내용은 상관없습니다.
// 가방이 비어 있지 않다면, 요소는 data[0]부터 data[manyItems-1]까지 저장되며,
// 그 외 영역의 값은 중요하지 않습니다.
private int[] data;
private int manyItems;
/**
* 초기 용량 10으로 빈 가방을 생성합니다.
* @postcondition
* 이 가방은 비어 있으며 초기 용량은 10입니다.
* @exception OutOfMemoryError
* new int[10]을 위한 메모리가 부족한 경우 발생합니다.
*/
public IntArrayBag() {
final int INITIAL_CAPACITY = 10;
manyItems = 0;
data = new int[INITIAL_CAPACITY];
}
/**
* 지정된 초기 용량으로 빈 가방을 생성합니다.
* @param initialCapacity
* 이 가방의 초기 용량
* @precondition
* initialCapacity는 0 이상이어야 합니다.
* @postcondition
* 이 가방은 비어 있으며 지정된 초기 용량을 가집니다.
* @exception IllegalArgumentException
* initialCapacity가 음수인 경우 발생합니다.
* @exception OutOfMemoryError
* 메모리 부족으로 배열을 만들 수 없는 경우 발생합니다.
*/
public IntArrayBag(int initialCapacity) {
if (initialCapacity < 0)
throw new IllegalArgumentException("The initialCapacity is negative: " + initialCapacity);
data = new int[initialCapacity];
manyItems = 0;
}
/**
* 가방에 새로운 요소를 하나 추가합니다.
* @param element
* 추가할 요소
* @postcondition
* 요소의 복사본이 가방에 추가됩니다.
* @exception OutOfMemoryError
* 용량 확장 시 메모리 부족한 경우 발생합니다.
*/
public void add(int element) {
if (manyItems == data.length) {
ensureCapacity((manyItems + 1) * 2);
}
data[manyItems++] = element;
}
/**
* 여러 요소를 가방에 한 번에 추가합니다.
* @param elements
* 추가할 요소들 (가변 인자)
* @postcondition
* 요소들의 복사본이 가방에 추가됩니다.
* @exception OutOfMemoryError
* 용량 확장 시 메모리 부족한 경우 발생합니다.
*/
public void addMany(int... elements) {
if (manyItems + elements.length > data.length) {
ensureCapacity((manyItems + elements.length) * 2);
}
System.arraycopy(elements, 0, data, manyItems, elements.length);
manyItems += elements.length;
}
/**
* 다른 가방의 모든 요소를 이 가방에 추가합니다.
* @param addend
* 추가할 다른 가방
* @precondition
* addend는 null이 아니어야 합니다.
* @postcondition
* addend의 모든 요소가 이 가방에 추가됩니다.
* @exception NullPointerException
* addend가 null인 경우 발생합니다.
* @exception OutOfMemoryError
* 메모리 부족 시 발생합니다.
*/
public void addAll(IntArrayBag addend) {
if (addend == null) throw new NullPointerException("addend cannot be null.");
ensureCapacity(manyItems + addend.manyItems);
System.arraycopy(addend.data, 0, data, manyItems, addend.manyItems);
manyItems += addend.manyItems;
}
/**
* 이 가방의 복사본을 생성합니다.
* @return
* 이 가방의 독립적인 복사본
* @exception OutOfMemoryError
* 복사본 생성을 위한 메모리가 부족한 경우 발생합니다.
*/
public IntArrayBag clone() {
IntArrayBag answer;
try {
answer = (IntArrayBag) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("This class does not implement Cloneable");
}
answer.data = data.clone();
return answer;
}
/**
* 특정 요소가 가방에 몇 번 나타나는지 셉니다.
* @param target
* 찾고자 하는 요소
* @return
* 요소의 발생 횟수
*/
public int countOccurrences(int target) {
int count = 0;
for (int i = 0; i < manyItems; i++) {
if (data[i] == target) count++;
}
return count;
}
/**
* 가방의 용량을 최소한 지정된 값 이상으로 확장합니다.
* @param minimumCapacity
* 확장할 최소 용량
* @postcondition
* 가방의 용량이 minimumCapacity 이상이 됩니다.
* @exception OutOfMemoryError
* 메모리 부족으로 인해 확장 불가할 경우 발생합니다.
*/
public void ensureCapacity(int minimumCapacity) {
if (data.length < minimumCapacity) {
int[] biggerArray = new int[minimumCapacity];
System.arraycopy(data, 0, biggerArray, 0, manyItems);
data = biggerArray;
}
}
/**
* 현재 가방의 용량을 반환합니다.
* @return
* 가방의 배열 용량
*/
public int getCapacity() {
return data.length;
}
/**
* 특정 요소를 가방에서 한 번 제거합니다.
* @param target
* 제거할 요소
* @postcondition
* 요소가 존재했다면 하나가 제거되고 true를 반환합니다.
* 존재하지 않았다면 false를 반환합니다.
*/
public boolean remove(int target) {
for (int i = 0; i < manyItems; i++) {
if (data[i] == target) {
manyItems--;
data[i] = data[manyItems];
return true;
}
}
return false;
}
/**
* 가방에 들어있는 요소 수를 반환합니다.
* @return
* 현재 요소 수
*/
public int size() {
return manyItems;
}
/**
* 가방의 용량을 현재 요소 수에 맞게 줄입니다.
* @postcondition
* 배열 용량이 요소 수와 같아집니다.
* @exception OutOfMemoryError
* 메모리 부족으로 배열 축소에 실패할 경우 발생합니다.
*/
public void trimToSize() {
if (data.length != manyItems) {
int[] trimmedArray = new int[manyItems];
System.arraycopy(data, 0, trimmedArray, 0, manyItems);
data = trimmedArray;
}
}
/**
* 두 가방을 합쳐 새로운 가방을 생성합니다.
* @param b1
* 첫 번째 가방
* @param b2
* 두 번째 가방
* @precondition
* b1과 b2는 null이 아니며,
* b1.getCapacity() + b2.getCapacity() <= Integer.MAX_VALUE 여야 합니다.
* @return
* 두 가방의 합집합
* @exception NullPointerException
* 인자가 null인 경우 발생합니다.
* @exception OutOfMemoryError
* 새로운 가방 생성에 필요한 메모리가 부족한 경우 발생합니다.
*/
public static IntArrayBag union(IntArrayBag b1, IntArrayBag b2) {
if (b1 == null || b2 == null) throw new NullPointerException("One or both bags are null.");
IntArrayBag answer = new IntArrayBag(b1.getCapacity() + b2.getCapacity());
System.arraycopy(b1.data, 0, answer.data, 0, b1.manyItems);
System.arraycopy(b2.data, 0, answer.data, b1.manyItems, b2.manyItems);
answer.manyItems = b1.manyItems + b2.manyItems;
return answer;
}
}
- IntArrayBag은 int [] 배열을 활용하여서 정수들을 저장하는 데이터 타입이다.
private int[] data;
private int manyItems;
- data: 실제로 정수들을 저장하는 배열
- manyItems: 현제 가방에 들어 있는 요소의 개수
생성자
public IntArrayBag()
- 기본 용량 10으로 가방을 초기화해준다.
- 내부 배열의 크기는 10으로 되고, 요소의 수는 0이다.
public IntArrayBag(int initialCapacity)
- 원하는 용량으로 초기화가 가능하다.
- 단 음수값이 매개변수로 들어오면 IllegalArgumentException이 발생한다.
메서드
public void add(int element)
- 데이터가 꽉 찼는지 검사하고 꽉 찼다면 용량을 두 배로 늘려 준다.
- 요소를 마지막 위치에 추가해 준다. (data [manyItems] = element)
- manyItem++ 을 해서 요소의 개수를 증가해 준다.
public void addMany(int... elements)
- 여러 인자를 한 번에 추가해 준다. (elements는 가변인자를 활용해 줌)
- elements의 길이와 manyItems의 개수가 배열 공간보다 크다면 2배만큼 확장해 준다.
if (manyItems + elements.length > data.length) {
ensureCapacity((manyItems + elements.length) * 2);
}
- System.arraycopy()로 elements를 복사해 준다.
- 마지막에 elements.length만큼을 manyItems에 더해준다.
public void addAll(IntArrayBag addend)
- addend가 null인지 먼저 확인해 주고 null인 경우에는 예외 발생해 준다.
- 그다음에는 ensureCapcity로 공간을 미리 확보해 준다.
- System.arraycopy()로 addend.data→this.data 에 복사해 준다.
- manyItems는 addend의 길이만큼 증가시켜 준다.
public int countOccurrences(int target)
- target이 몇 개 있는지 세는 기능을 한다.
public boolean remove(int target)
- target 값을 한 번만 삭제한다.
- 0번부터 끝까지 순회하면서 값을 찾으면 data [manyItems-1]로 현제 위치를 대체해 주고 manyItems은 1을 빼준다.
- 만약 못 찾으면 false를 리턴해준다.
public IntArrayBag clone()
- 가방 전체를 복사해 준다.
- super.clone()으로 얕은 복사를 해주고 data도. clone으로 깊은 복사를 해준다.
- 완전히 독립적인 복사된 객체를 리턴해준다.
public void ensureCapacity(int minimumCapacity)
- minimumCapcity이상으로 확장해 준다.
- 만약 minmumCapacity보다 작다면 새 배열을 만들고 System.arraycopy() 복사해 준다.
public void trimToSize()
- 배열의 사이즈를 manyItems, 즉 원소의 개수에 맞춰서 줄여준다.
- data.length!=manyItems인 경우에만 작동한다.
public int getCapacity()
- 배열의 전체 크기를 반환해 준다. (=data.length)
public int size()
- 가방에 들어 있는 원소의 개수를 반환해준다. (=manyItems)
public static IntArrayBag union(IntArrayBag b1, IntArrayBag b2)
- 두 가방을 합쳐 새로운 가방을 반환해준다.
- 둘 중에 null 값이 있으면 예외 발생해 준다.
- answer 객체에는 두 객체의 배열 사이즈의 합만큼의 배열을 만들어 준다.
- 그 후에는 System.arraycopy()로 두 배열을 answer에 복사해 준다.
- answer의 manyItems 또한 업데이트해주는 것을 잊으면 안 된다.
실행 예제
public class IntArrayBagTest {
public static void main(String[] args) {
IntArrayBag bag1 = new IntArrayBag();
bag1.add(10);
bag1.add(20);
bag1.addMany(30, 40, 20);
System.out.println("Bag1 Size: " + bag1.size()); // 5
System.out.println("Occurrences of 20: " + bag1.countOccurrences(20)); // 2
IntArrayBag bag2 = new IntArrayBag();
bag2.addMany(50, 60);
IntArrayBag unionBag = IntArrayBag.union(bag1, bag2);
System.out.println("Union Bag Size: " + unionBag.size()); // 7
bag1.remove(20);
System.out.println("Bag1 Size After Removal: " + bag1.size()); // 4
System.out.println("Occurrences of 20 after one removal: " + bag1.countOccurrences(20)); // 1
bag1.trimToSize();
System.out.println("Bag1 Capacity After Trim: " + bag1.getCapacity()); // 4
}
}
Bag1 Size: 5
Occurrences of 20: 2
Union Bag Size: 7
Bag1 Size After Removal: 4
Occurrences of 20 after one removal: 1
Bag1 Capacity After Trim: 4'자료구조' 카테고리의 다른 글
| IntStack 클래스 (0) | 2025.04.19 |
|---|---|
| IntNode 클래스 (0) | 2025.04.19 |
| IntLinkedBag 클래스 (0) | 2025.04.18 |
| Location 클래스 (1) | 2025.04.17 |
| Throttle 클래스 (0) | 2025.04.17 |