본문 바로가기
국비 교육/백엔드(Java, Spring)

[자바] 배열 Array

by 육츠 2024. 1. 22.
Contents 접기

자료구조 

- 선형 Linear

메모리상 데이터를 인접하게 저장하는 방법  예) Array(ArrayList), Stack, Queue

Array

끝에 주소를 찾아가기 편하지만 삭제나 끼워넣기를 하게되면 너무 많은 시간을 사용하게 된다. ( = 효율적이지 못함.)
탐색의 경우에는 정렬을 해두는 것이 편리하다.

 

- 비선형 Non Linear

메모리상 데이터를 비선형적으로 저장하는 방법  예) LinkedList, Tree, 망형 = 네트워크형, Map(HashMap), Set(HashSet)
* Hash = 해당하는 value 값에 주소를 설정해주는 알고리즘을 의미한다.
* 비선형 : 데이터가 여러곳에 퍼져있다.

LinkedList

삭제나 끼워넣기는 편하지만 데이터가 흩어져 있기 때문에 끝 인덱스를 바로 찾는 것이 오래 걸린다.

 

배열 Array

선언과 생성

선언 생성
타입[] 배열명;
타입 배열명;
타입[] 배열명 = new 타입[개수];

 

public class ArrayTest01 {

	public static void main(String[] args) {
//		int[] arr1; // 정수형 1차원 배열
//		arr1 = new int[10]; //  선언
//		
//		System.out.println(arr1); 
//		System.out.println(arr1[0]); // 0 으로 초기화 된 상태
//		System.out.println(arr1.length);
		// System.out.println(arr[-1]); 파이썬 과 다른 점
		// System.out.println(arr[10]); 0-9 까지 있는 것
		
		int[] arr1 = new int[10];
		
		int[] arr2 = new int[]{1,2,3,4,5}; // 방의 개수를 뒤에 원소 개수를 보고 알아냄;
		
		int[] arr3 = {1,2,3,4,5}; // 선언과 동시에 초기화
		
		int[] arr4 = new int[10];
		
		System.out.println("배열의 길이는 " + arr3.length);
		
		for (int i = 0; i < arr3.length; i++){
			System.out.println(arr3[i]);
		}
		
		
	}

}

 

System.out.println(arr[-1]); ==> 파이썬과 다르게 음수의 표현이 불가능하다. 
배열이름.length ==> 배열의 길이를 알 수 있는 방법

public class ArrayTest02 {

	public static void main(String[] args) {
		double[] darr = new double[10];
		
		// 난수 이용 초기화하기
		for(int i = 0; i<darr.length; ++i)
			darr[i] = Math.random(); // double value 반환 (난수범위: 0 ~ 1)
		
		// 출력
		for(int i = 0; i<darr.length; ++i)
			System.out.print(darr[i] + " ");
		System.out.println();
		
		
		// 2)  난수 이용 초기화하ㄱ기
		for(int i = 0; i<darr.length; ++i)
			darr[i] = Math.random()* 100 ; // double value 반환 (난수범위: 0 ~ 100) : 100은 나오지 않음
		
		// 출력
		for(int i = 0; i<darr.length; ++i)
			System.out.print(darr[i] + " ");
		System.out.println();
		
		// 3)  난수 이용 초기화하ㄱ기
		int[] arr = new int[10];
		
		// double 형태로 int에 넣을 수 없음
		for(int i = 0; i<arr.length; ++i)
			arr[i] = (int)(Math.random() *100 +1 -50 );// 난수 범위 - 50 ~49
			//	arr[i] = (int)(Math.random() *100 +1); // (난수범위: 1~100)
			//	arr[i] = (int)(Math.random()* 100) ; // (난수범위 : 0 ~ 99)
			// (int)Math.random()* 100 = Math.random() 만 캐스팅 되상이 되어 전부 0으로 출력됨
		
		// *100 =  발생시키려는 난수의 개수를 의미
		
		
		// 출력
		for(int i = 0; i<arr.length; ++i)
			System.out.print(arr[i] + " ");
		System.out.println();
		

	}

}
코드 난수 범위
*100 =  발생시키려는 난수의 개수를 의미한다.
darr[i] = Math.random();  난수범위: 0 ~ 1
arr[i] = (int)(Math.random()* 100)

(int)Math.random()* 100 
= Math.random() 만 캐스팅 대상이 되어 전부 0으로 출력됨
난수범위 : 0 ~ 99(100은 나오지 않는다.)
arr[i] = (int)(Math.random() *100 +1);  난수범위: 1 ~ 100
arr[i] = (int)(Math.random() *100 +1 -50 ); 난수 범위: -50 ~ 49

 

문자열배열 선언과 초기화 방법

public class ArrayTest03 {

	public static void main(String[] args) {
		String[] sary = new String[10]; // sary 는 문자열이 아닌 문자열 참조값이 들어있음
		int[] iary = new int[10];
		
//		sary[0] = "봄";
//		String s = "봄";
		
		String[] sary1 = new String[]{"봄","여름","가을","겨울"};
		String[] sary2 =  {"봄","여름","가을","겨울"};
		String[] sary3 = {
				new String("봄"),
				new String("여름"),
				new String("가을"),
				new String("겨울")
				};
	}

}

 

2차원 배열

public class ArrayTest04 {

	public static void main(String[] args) {
		int[][] iarr = new int [3][5]; // 15개의 방을 가지는 2차원 배열
		/* 3행 5열의 2차원 배열
		 * □ □ □ □ □
		 * □ □ □ □ □
		 * □ □ □ □ □
		 */
		
		int count = 0;
		for (int i = 0; i< iarr.length; i++) 	// iarr.length = 3
			for(int j =0; j<iarr[i].length; j++) //iarr[i].length = 5
				iarr[i][j] = ++count;
                
		
		for(int i = 0; i < iarr.length; i++) {
			for(int j=0; j<iarr[i].length; j++) {
				System.out.printf("%3d", iarr[i][j]);
			}
		System.out.println();
		}
	}

}

1   2   3   4   5
6   7   8   9   10
11 12 13 14 15

코드 & 의미 -1 코드 & 의미 -2 
for (int i = 0; i< iarr.length; i++) for(int j =0; j<iarr[i].length; j++)
  ㅁ -> ㅁ -> ㅁ ㅁ ㅁ ㅁ ㅁ
           ㅁ -> ㅁ ㅁ ㅁ ㅁ ㅁ
           ㅁ -> ㅁ ㅁ ㅁ ㅁ ㅁ
ㅁ ->   ㅁ ㅁ ㅁ ㅁ ㅁ
           |    |   |    |   |
           ㅁ ㅁ ㅁ ㅁ
           ㅁ ㅁ ㅁ ㅁ
           ㅁ ㅁ ㅁ ㅁ
iarr.length = 3 iarr[i].length = 5

 

향상된 for문

 

배열과 같이 여러개의 데이터로 구성된 데이터를 차례대로 모든 데이터를 순회하고자 할 때 사용하는 for문이다.
= 전체를 조회하는 목적으로 사용하는 for문이다.

배열이나 ArrayList 함께 사용할때 유용하며, length 없이 사용할 수 있다.

for (타입 변수 : 배열명){
    // 명령문
}

아래 코드에서의 예시

코드 의미
for(int temp : iarr) System.out.print(temp + " "); 타입변수 : temp(int 형)
배열명 : iarr
명령문 : System.out.print(temp + " ")

 

선택 정렬 알고리즘 = 기준 열을 지정한 후 나머지 모든 열과 비교

public class SelectionSort {

	public static void main(String[] args) {
		
		int[] iarr = new int[10];
		
		// 데이터를 발생해서 초기화
		for(int i = 0; i<iarr.length; i++)
			iarr[i] = (int)(Math.random()*99+1);  
		    // 0 이상 100 미만의 정수
		
		System.out.print("> 정렬 전: ");
		for(int temp : iarr) System.out.print(temp + " ");
		
		System.out.println("\n");
		
		for(int i = 0; i<iarr.length; i++) {
			for (int j = i +1;j<iarr.length; j++) {
				if(iarr[i] > iarr[j]) {
					int temp = iarr[i];
					iarr[i] = iarr[j];
					iarr[j] = temp;
				}
			}
		}
		
		System.out.print("> 정렬 후: ");
		for(int temp: iarr) System.out.print(temp + " ");
		
		System.out.println("\n");

	}

}

> 정렬 전: 22 96 18 45 58 89 94 68 61 34

> 정렬 후: 18 22 34 45 58 61 68 89 94 96

코드 의미
for(int i = 0; i<iarr.length; i++) {
    for (int j = i +1;j<iarr.length; j++) {
        if(iarr[i] > iarr[j]) {
            int temp = iarr[i];
            iarr[i] = iarr[j];
            iarr[j] = temp;
         }
    }
}

i 값 1회당 j 값 10개 반복

 i 값이 이후 모든 j보다 클 경우 자리바꿈
 = 0번째 값이 제일 작아진다. = 오름차순
 
 iarr[j] > iarr[i] 라면
 i 값이 이후 모든 j보다 작아야 자리를 바꾼다.
 = 0번째 값이 제일 커진다. = 내림차순
 

 

# 문제

[Q] 데이터 교환

1차원 정수형 배열 10개를 선언하고 1~100 사이의 난수로 초기화 후 처리 전 출력, 아래의 처리를 한 후 출력하여 결과를 확인
(데이터가 대칭으로 변경되어야 함.)

<처리 작업>
0번 - 9번 교환
1번 - 8번 교환
2번 - 7번 교환
...

public class Exam25 {

	public static void main(String[] args) {
		int[] arr = new int[10];
		int temp;

		for(int i = 0 ; i<arr.length; ++i)
			arr[i] = (int)(Math.random()* 99 + 1); //100은 포함 안되게

		System.out.print("처리 전: ");
		for(int i=0; i<arr.length; ++i) 
			System.out.print(arr[i] + " ");
		
		
		 for(int i=0; i<arr.length/2; ++i) 
         // 홀수인 경우에는 가운데는 건들이지 않는다.
         
			temp = arr[i];
			arr[i] = arr[arr.length-(i+1)];
			arr[arr.length-(i+1)] = temp
		 
		 System.out.print("처리 후: ");
		for(int i=0; i<arr.length; ++i) 
			System.out.print(arr[i] + " ");
		
        
        
        }

}

 

[Q] 중복제거

1차원 정수형 배열 5개 선언하고 1부터 100 사이의 난수로 초기화. 이때 이미 발생된 동일한 값은 배열에 넣을수 없다,

<실행 예>
## 결과 
5 10 74 50 12

temp 에 난수 중 하나를 넣고 
동일한 배열이 있는지 확인
없으면 배열에 추가 (비교하는 건 추가 되는 만큼 커진다 )

public class Exam26 {

	public static void main(String[] args) {
		int[] arr = new int[5];
		int temp;

		for(int i = 0 ; i<arr.length; ++i)
			for (int j = 0; j <= i; ++j) {
				temp = (int)(Math.random()* 99 + 1);
		
				if(temp != arr[i] & temp != arr[j])
					arr[i] = temp; 
			}
            
		/* 교수님 코드
		for(int i = 0 ; i<arr.length; ++i) {
			temp = (int)(Math.random()* 99 + 1);
			arr[i] = temp;
			for (int j = 0; j < i; ++j) {
				if (arr[j] == temp) {
					--i;
					break; // 자신을 감싸고 있는 첫 번째 for 문을 멈춤
				}
			}
		}
		
		temp 변수를 없앤다면?
		for(int i = 0 ; i<arr.length; ++i) {
			arr[i] = (int)(Math.random()* 99 + 1);
			for (int j = 0; j < i; ++j) {
				if (arr[j] == arr[i]) {
					--i;
		*/

		System.out.print("결과: ");
		for(int i=0; i<arr.length; ++i) 
			System.out.print(arr[i] + " ");
			
	}

}
코드 의미
for(int i = 0 ; i<arr.length; ++i) {
    temp = (int)(Math.random()* 99 + 1);
    arr[i] = temp;
    for (int j = 0; j < i; ++j) {
        if (arr[j] == temp) {
        --i;
        break;
         }
    }
}
break; 가 자신을 감싸고 있는 첫 번째 for 문을 멈춘다.
= 두 개의 괄호(if 문과 감싸고 있던 for 문)를 지나면 처음 돌린 for 문을 만나게 되는 것이다.

 

[Q] 방 3개짜리 문제 int[] 생성. 임의의 값을 넣은 후 정렬하시오

5 1 8
1 5 8

public class Exam27 {

	public static void main(String[] args) {
		int[] iarr = {9,4,7};
		int temp = 0;
		
		for(int i = 0 ; i < iarr.length; i++) {
			for(int j = 0; j< i; j++) {
				if(iarr[j]>iarr[i]) {
					temp = iarr[j];
					iarr[j] = iarr[i];
					iarr[i] = temp;
							
				}
			}
		}
		
		for (int i =0; i < iarr.length; i++ )
			System.out.print(iarr[i] + " ");
		

	}

}

 

[Q] 5x5를 2차원으로 만들기

만들고 처음 5x4만 값 채우기

public class Exam28 {

	public static void main(String[] args) {
		
		// 1. 배열 생성
		int[][] iarr = new int [5][5];
		
		// 2. 난수로 초기화
		for(int i = 0; i < iarr.length; i++)
			for(int j =0; j<iarr[i].length-1; j++){
				iarr[i][j] = (int)(Math.random() *20 +1);
				iarr[i][4] += iarr[i][j];
			}
		// 3. 출력
		for(int i = 0; i < iarr.length; i++) {
			for(int j =0; j<iarr[i].length; j++) {
				System.out.printf("%3d", iarr[i][j]);
			}
			System.out.println();
		}
		
	}

}
코드 의미
for (int i = 0; i < Iarr.length; i++) {
    for (int j = 0; j < Iarr[i].length-1; j++) {
         Iarr[i][j] = (int)(Math.random() * 20 + 1); 
         Iarr[i][4] += Iarr[i][j];
각 행의 맨 마지막 열에 이전 열 값들의 합계가 채워지는 것
= 각 행의 마지막 열에 값을 누적

진짜 바보다,,  i가 행이고 j 가 열인데 난 왜,,, 그 반대로 생각하고 있었을까,,,

 

[Q] 로또게임

7개의 크기를 갖는 배열을 생성하고 1~46까지의 정수 난수를 발생 시켜 초기화 한다. 1~46 까지의 정수 난수를 발생시켜 초기화 한다.
사용자는 로또 내의 숫자를 맞추어 1등 ~5등, 그리고 당첨 여부를 출력하는 프로그램을 작성하시오
 
1) 로또번호는 프로그램이 시작되면 바로 발생됨
2) 사용자에게 물어봄
- 몇번 게임하실래요? : 3 ==> 3행
- 직접 기입할 것인지? 컴퓨터가 발생한 숫자를 로또번호로 사용할 것인지 물어보고 각각 다르게 처리할 것