참고: Doit 자료구조+알고리즘 입문 자바편 | 117페이지 연습문제 Q3
다음의 메서드를 작성해야 한다.
static searchIdx(int[] a, int n, int key, int[] idx)
인자의 형식에서 보면 알 수 있듯이, ArrayList같은 좋은 배열 형식을 사용해서는 안 된다. 그냥 순수한 배열 int[]를 사용하여 문제가 요구하고 있는 메서드를 작성해보자.
자 그럼
요솟수가 n인 배열 a에서, 원하는 key와 동일한 값을 가지는 요소의 인덱스를 반환하는 메서드를 만들어보자.
먼저 작성한 코드는 다음과 같다.
package doit;
import java.util.*;
public class Q3 {
static int searchIdx(int[] a, int n, int key, int[] idx) {
int k=0;
for(int i=0; i<n; i++) {
if(key==a[i]) {
idx[k]=i; k++;
}
}
return k;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("요솟수: ");
int n = scan.nextInt();
int[] a = new int[n];
for(int k=0; k<n; k++) {
System.out.print("a["+k+"]:");
a[k] = scan.nextInt();
}
System.out.print("배열에서 찾을 키: "); int key = scan.nextInt();
System.out.println("해당 키를 찾습니다.");
int[] idx = new int[n];
int total = searchIdx(a, n, key, idx);
int[] index = new int[total];
for(int j=0; j<total; j++) {
index[j]=idx[j];
}
System.out.println("찾은 요소 수: "+total);
System.out.print("{ ");
for(int i: index) System.out.print(""+i+" "); System.out.print("}");
}
}
● 헤맸던 부분:
ArrayList가 아닌, 일반적인 int[]배열 등은 배열의 크기가 고정되어 있기 때문에, 필요에 따라 크기를 마음대로 하기가 어렵다. 크기를 크게 잡으면 불필요한 초기 요소인 0이 들어갈 수밖에 없고, 크기를 작게 잡으면 더 이상 요소를 추가할 수 없을지도 모른다. 그래서 뽑아낸 요소의 인덱스를 저장하는 배열 idx[]를 어떻게 다뤄야 할지 생각해야 했다.
그래서 선택한 방법은, 인덱스배열 idx[]의 크기를 일단 배열의 요솟수 n으로 설정했다. 그리고 searchIdx메서드 안에서 그 배열에 뽑아낸 인덱스를 담았다. 인덱스를 담음과 동시에, 담은 횟수 즉 뽑아낸 요소의 총 갯수를 변수 k를 통해 카운트했다. searchIdx 메서드가 반환하는 값은 key와 일치하는 요소수인 k이다. 그리고나서 searchIdx메소드를 빠져나온 뒤 메인메소드에서, 인덱스 배열 idx[]의 요소 개수인 k를 가지고 다시 새로운 인덱스 배열 int[] index를 생성했다. 왜냐하면, 원하는 요소만으로 구성되어 배열길이가 딱 맞추어진 인덱스배열을 만들어주기 위함이다.
즉, 맨 처음의 인덱스 배열 inx는 그냥 배열의 크기를 '가능한 최대 수'로 잡은 큰 배열이고, searchIdx메서드 실행 뒤 새로 만들어준 배열 index는 배열 길이를 딱 원하는 만큼 설정해준 찐 인덱스 배열이다.
이렇게 배열 index의 본체를 생성해준 다음에, idx에 있던 내용을 옮겨담아주는 방식으로 만들었다.
그 실행 결과는:
깔끔하게 { 1 3 7 }만 표시해주게끔 완성했다.
지금 다시 가만히 생각해보면 그냥 idx배열에서 k만큼(total)만큼만 for문을 돌려서 요소를 표시하는 방법도 괜찮을 듯하다. 굳이 새로운 인덱스배열 index를 만들지 않아도 되는 방법으로 말이다.
● 답안과의 비교:
답안도 역시 idx배열 요솟수를 n으로 설정했다. 그리고 서치 메서드 안에서 idx배열에 count방식을 이용하여 차곡차곡 원하는 요소의 인덱스를 저장했다. 그리고 그 count를 반환함으로써 찾은 요소 수를 반환하게 했다. 여기까지 내가 작성한 방식과 동일하다.
차이가 있었던 부분은 찾은 요소를 표시하는 방식이다. 답안에서는 idx배열에서 요소를 담은 만큼만 (즉, 내가 쓴 코드에서 k(or total)만큼만) for문을 돌려서 찾은 요소의 인덱스를 표시했다. 내가 조금 전에 뒤늦게 떠올린 방법 말이다.
● 간과한 부분:
찾을 key를 입력받을 때, 그 key가 배열에 없을 수도 있음을 아예 떠올리지 않았다.
어차피 내가 작성한 프로그램에서 "찾은 요소 수: 0"으로 표시되기는 하겠지만 그래도 생각을 했냐 못했냐는 아주 큰 차이니까 앞으로 이 부분 조심하자.
'자료구조 + 알고리즘' 카테고리의 다른 글
이진 검색 - 중복요소의 맨 앞 인덱스 찾아내기 | 반복문의 유연한 사용이 필요하겠다. (0) | 2021.06.28 |
---|---|
이진 검색 과정을 출력하는 프로그램 작성하기 (0) | 2021.06.28 |
[알고리즘|자료구조] 해시란? | 해시법(hasing) (0) | 2021.03.23 |
챕터2 배열 - 연습문제 Q4, Q5 [Doit! 자료구조와 함께 배우는 알고리즘 입문 자바편] (0) | 2021.01.29 |
[for문] 반복 알고리즘 연습 / 다양한 피라미드 (0) | 2021.01.13 |