Java의 정석: CHAPTER 05 배열(Array)

mucha·2023년 4월 17일

Java의 정석

목록 보기
5/6
post-thumbnail

CHAPTER 05 배열(Array)

1. 배열(array)


1.1 배열(array)이란?

같은 타입의 여러 변수를 하나의 묶음으로 다루는 것.

int[] score = new int[5];

변수 score는 배열을 다루는데 필요한 참조변수일 뿐 값을 저장하기 위한 공간은 아님.

1.2 배열의 선언과 생성

타입[] 변수이름;
변수이름 = new 타입[길이];

1.3 배열의 길이와 인덱스

인덱스: 배열의 요소마다 붙여진 일련번호
범위는 0부터 배열길이-1까지

score[3] = 100; // 배열 score의 4번째 요소에 100을 저장
int value = score[3]; // 배열 score의 4번째 요소에 저장된 값을 읽어서 value에 저장
class ArrayEx1 {
	public static void main(String[] args) { 
		int[] score = new int[5];
		int k = 1;

		score[0] = 50;
		score[1] = 60;
		score[k+1] = 70;   // score[2] = 70
		score[3] = 80;
		score[4] = 90;

		int tmp = score[k+2] + score[4];  // int tmp = score[3] + score[4]

	    // for문으로 배열의 모든 요소를 출력한다.
		for(int i=0; i < 5; i++) {
			System.out.printf("score[%d]:%d%n",i, score[i]);		
		}

		System.out.printf("tmp:%d%n", tmp);
		System.out.printf("score[%d]:%d%n",7,score[7]); //index의 범위를 벗어난 값
	} // main
}

배열의 길이
배열의 길이는 int범위의 양의 정수도 포함이어야 함.

배열이름.length

int[] arr = new int[5];
int temp = arr.length; //temp=5

길이는 상수이므로 변경 불가

배열의 길이 변경하기
1. 더 큰 배열을 새로 생성
2. 기존 배열의 내용을 새로운 배열에 복사

1.4 배열의 초기화

int[] score = new int[5];
score[0] = 50;
score[1] = 60;
score[2] = 70;
score[3] = 80;
score[4] = 90;

int[] score = new int[]{50, 60, 70, 80, 90};

배열의 출력

import java.util.*;  // Arrays.toString()을 사용하기 위해 추가

class ArrayEx2 {
	public static void main(String[] args) {
		int[] iArr1 = new int[10];
		int[] iArr2 = new int[10];
//		int[] iArr3 = new int[]{100, 95, 80, 70, 60};
		int[] iArr3 = {100, 95, 80, 70, 60};
		char[] chArr = {'a', 'b', 'c', 'd'};

		for (int i=0; i < iArr1.length ; i++ ) {
			iArr1[i] = i + 1; // 1~10의 숫자를 순서대로 배열에 넣는다.
		}

		for (int i=0; i < iArr2.length ; i++ ) {
			iArr2[i] = (int)(Math.random()*10) + 1; // 1~10의 값을 배열에 저장
		}

		// 배열에 저장된 값들을 출력한다.
		for(int i=0; i < iArr1.length;i++) {
			System.out.print(iArr1[i]+",");	
		}
		System.out.println();													
		System.out.println(Arrays.toString(iArr2));
		System.out.println(Arrays.toString(iArr3));
		System.out.println(Arrays.toString(chArr));
		System.out.println(iArr3);
		System.out.println(chArr);
	}
}

1.5 배열의 복사

for문을 이용하여 복사하는 방법
1. 배열 arr의 길이인 arr.length의 값이 5이므로 길이가 10인 int배열 tmp가 생성. tmp의 각 요소는 int의 기본값인 0으로 초기화
2. for문을 이용하여 배열 arr의 모든 요소에 저장한 값을 하나씩 배열 tmp에 복사.
3. 참조변수 arr에 참조변수 tmp의 값을 저장.

```java
class ArrayEx3{
	public static void main(String[] args) {
		int[] arr = new int[5];

		// 배열 arr에 1~5를 저장한다.
		for(int i=0; i < arr.length;i++) 
			arr[i] = i + 1;

		System.out.println("변경전 - arr.length:"+arr.length);	
		for(int i=0; i < arr.length;i++) 
			System.out.println("arr["+i+"]:"+arr[i]);	

		int[] tmp = new int[arr.length*2];

		// 배열 arr에 저장된 값들을 배열 tmp에 복사한다.
		for(int i=0; i < arr.length;i++) 
			tmp[i] = arr[i];

		arr = tmp;  // tmp에 저장된 값을 arr에 저장한다.

		System.out.println("변경후 - arr.length:"+arr.length);	
		for(int i=0; i < arr.length;i++) 
			System.out.println("arr["+i+"]:"+arr[i]);	
	}
}
```

System.arraycopy( )를 이용한 배열의 복사

class ArrayEx4 {
	public static void main(String[] args) {
		char[] abc = { 'A', 'B', 'C', 'D'};
		char[] num = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
		System.out.println(abc);
		System.out.println(num);

		// 배열 abc와 num을 붙여서 하나의 배열(result)로 만든다.
		char[] result = new char[abc.length+num.length];
		System.arraycopy(abc, 0, result, 0, abc.length);
		System.arraycopy(num, 0, result, abc.length, num.length);
		System.out.println(result);

		// 배열 abc을 배열 num의 첫 번째 위치부터 배열 abc의 길이만큼 복사
		System.arraycopy(abc, 0, num, 0, abc.length);	
		System.out.println(num);

	     // number의 인덱스6 위치에 3개를 복사
		System.arraycopy(abc, 0, num, 6, 3);
		System.out.println(num);
	}
}

char배열은 for문 사용 없이 print()나 println()으로 배열에 저장된 모든 문자 출력 가능.

1.6 배열의 활용

총합과 평균

class ArrayEx5 {
	public static void main(String[] args) {
		int sum =0;				// 총점을 저장하기 위한 변수
		float average = 0f;		// 평균을 저장하기 위한 변수

		int[] score = {100, 88, 100, 100, 90};

		for (int i=0; i < score.length ; i++ ) {
			sum += score[i];
		}

		average = sum / (float)score.length ; // 계산결과를 float로 얻기 위함.

		System.out.println("총점 : " + sum);
		System.out.println("평균 : " + average);
	}
}

최대값과 최소값

class ArrayEx6 { 
	public static void main(String[] args) { 
		int[] score = { 79, 88, 91, 33, 100, 55, 95}; 

		int max = score[0]; // 배열의 첫 번째 값으로 최대값을 초기화 한다. 
		int min = score[0]; // 배열의 첫 번째 값으로 최소값을 초기화 한다. 

		for(int i=1; i < score.length;i++) {
			if(score[i] > max) { 
				max = score[i]; 
			} else if(score[i] < min) { 
				min = score[i]; 
			} 
		} // end of for 

		System.out.println("최대값 :" + max);       
		System.out.println("최소값 :" + min);       
	} // end of main 
} // end of class

섞기

class ArrayEx7 {
	public static void main(String[] args) {
		int[] numArr = new int[10];

		for (int i=0; i < numArr.length ; i++ ) {
             numArr[i] = i;  // 배열을 0~9의 숫자로 초기화한다.
			System.out.print(numArr[i]);  
		}
		System.out.println();

		for (int i=0; i < 100; i++ ) {
			int n = (int)(Math.random() * 10);	// 0~9중의 한 값을 임의로 얻는다.

			int tmp = numArr[0];
			numArr[0] = numArr[n];
			numArr[n] = tmp;
		}

		for (int i=0; i < numArr.length ; i++ )
			System.out.print(numArr[i]);		
	} // main의 끝
}
class ArrayEx8 { 
	public static void main(String[] args) { 
		// 45개의 정수값을 저장하기 위한 배열 생성. 
		int[] ball = new int[45];       

		// 배열의 각 요소에 1~45의 값을 저장한다. 
		for(int i=0; i < ball.length; i++)       
			ball[i] = i+1;    // ball[0]에 1이 저장된다.

		int temp = 0;  // 두 값을 바꾸는데 사용할 임시변수 
		int j = 0;     // 임의의 값을 얻어서 저장할 변수 

		// 배열의 i번째 요소와 임의의 요소에 저장된 값을 서로 바꿔서 값을 섞는다. 
		// 0번째 부터 5번째 요소까지 모두 6개만 바꾼다.
		for(int i=0; i < 6; i++) {       
			j = (int)(Math.random() * 45); // 0~44범위의 임의의 값을 얻는다. 
			temp     = ball[i]; 
			ball[i] = ball[j]; 
			ball[j] = temp; 
		} 

		// 배열 ball의 앞에서 부터 6개의 요소를 출력한다.
		for(int i=0; i < 6; i++) 
			System.out.printf("ball[%d]=%d%n", i, ball[i]); 
	} 
}

임의의 값으로 배열 채우기

import java.util.*;  // Arrays.toString()을 사용하기 위해 추가

class ArrayEx9 {
	public static void main(String[] args) {
		int[] code = { -4, -1, 3, 6, 11 };  // 불연속적인 값들로 구성된 배열
		int[] arr = new int[10];

		for (int i=0; i < arr.length ; i++ ) {
			int tmp = (int)(Math.random() * code.length);
			arr[i] = code[tmp];
		}

		System.out.println(Arrays.toString(arr));
	} // main의 끝
}

정렬하기

class ArrayEx10 {
	public static void main(String[] args) {
		int[] numArr = new int[10];

		for (int i=0; i < numArr.length ; i++ ) {
			System.out.print(numArr[i] = (int)(Math.random() * 10));
		}
		System.out.println();

		for (int i=0; i < numArr.length-1 ; i++ ) {
			boolean changed = false;	// 자리바꿈이 발생했는지를 체크한다.

			for (int j=0; j < numArr.length-1-i ;j++) {
				if(numArr[j] > numArr[j+1]) { // 옆의 값이 작으면 서로 바꾼다.
					int temp = numArr[j];
					numArr[j] = numArr[j+1];
					numArr[j+1] = temp;
					changed = true;	// 자리바꿈이 발생했으니 changed를 true로.
				}
			} // end for j

			if (!changed) break;	// 자리바꿈이 없으면 반복문을 벗어난다.

			for(int k=0; k<numArr.length;k++)
				System.out.print(numArr[k]); // 정렬된 결과를 출력한다.
			System.out.println();
		} // end for i
	} // main의 끝
}

빈도수 구하기

class ArrayEx11 {
	public static void main(String[] args) {
		int[] numArr  = new int[10];
		int[] counter = new int[10];

		for (int i=0; i < numArr.length ; i++ ) {
			numArr[i] = (int)(Math.random() * 10); // 0~9의 임의의 수를 배열에 저장
			System.out.print(numArr[i]);
		}
		System.out.println();

		for (int i=0; i < numArr.length ; i++ ) {
			counter[numArr[i]]++;
		}

		for (int i=0; i < numArr.length ; i++ ) {
			System.out.println( i +"의 개수 :"+ counter[i]);
		}
	} // main의 끝
}

2. String배열


2.1 String배열의 선언과 생성

String[] name = new String[3];
3개의 String타입의 참조변수를 저장하기 위한 공간이 마련, 참조형 변수의 기본값은 null이므로 각 요소의 값은 null로 초기화

변수의 타입에 따른 기본 값

자료형기본값
booleanfalse
char‘\u0000’
byte, short, int0
long0L
float0.0f
double0.0d 또는 0.0
참조형 변수null

2.2 String배열의 초기화

// 1. 배열의 각 요소에 문자열 지정
String[] name = new String[3];
name[0] = "kim";
name[1] = "park";
name[2] = "Lee";

// 2. 괄호 사용 간단히 초기화
String[] name = new String[]{"kim", "park", "lee");
String[] name = {"kim", "park", "lee");

배열에 실제 객체가 아닌 객체의 주소가 저장되어 있음.
참조형 배열의 경우 배열에 저장되는 것은 객체의 주소.

class ArrayEx12 {
	public static void main(String[] args) {
		String[] names = {"Kim", "Park", "Yi"};

		for(int i=0; i < names.length;i++) {
			System.out.println("names["+i+"]:"+names[i]);
		}

		String tmp = names[2]; // 배열 names의 세 번째요소를 tmp에 저장
		System.out.println("tmp:"+tmp);

		names[0] = "Yu"; // 배열 names의 첫 번째 요소를 "Yu"로 변경

		for(String str : names)   // 향상된 for문
			System.out.println(str);
	} // main
}

2.3 char배열과 String클래스

String클래스는 char배열에 기능(메서드)를 추가한 것.
char배열과 String 클래스의 차이 → String객체는 읽을 수만 있음.

String클래스의 주요 매서드

메서드설명
char charAt(int index)문자열에서 해당 위치(index)에 있는 문자 반환
int length()문자열의 길이 반환.
String substring(int from, int to)문자열에서 해당범위(from~to)에 있는 문자열 반환.
boolean equals(String str)문자열의 내용이 같은지 확인.
같으면 true, 다르면 false
char[] toCharArray()문자열을 문자배열(char[])로 변환하여 반환.
// 1. char charAt(int index)
String str = "ABCDE";
char ch = str.charAt(3); //ch = "D"

// 2. int length()
String str = "ABCDE";
int num = str.length(); // num = 5

// 3. String substring(int from, int to)
String str "012345"; 
String sub = str.substring(1,4); // sub = '123'

// 4. boolean equals(String str)
String str1 = "abc";
String str2 = "abc";
String str3 = "abC";
boolean res1 = str1.equals(str2); // true
boolean res2 = str2.equals(str3); // false

// 5. char[] toCharArray()
String str = "abc";
char[] res = str.toCharArray(); // ['a', 'b', 'c'];

char배열과 String클래스의 변환

char배열을 String클래스로 변환하거나, 또는 그 반대로 변환해야하는 경우.

char[] chArr = {"a", "b", "c"};
String str = new String(chArr);
char[] tmp = str.toCharArray();

2.4 커맨드 라인을 통해 입력받기

프로그램을 실행할 때 클래스 이름 뒤에 공백문자로 구분하여 여러 개의 문자열을 프로그램에 전달 가능.
커멘드라인을 통해 입력된 두 문자열은 String 배열에 담겨 MainTest클래스의 main메서드의 매개변수(args)에 전달.
main메서드 내에서 args[0], args[1]과 같은 방식으로 커맨드라인으로부터 전달받은 문자열에 접근 가능.

/* c:\jdk1.8\work\ch5>java ArrayEx16 abc 123 "Hello World"
args[0] = abc
args[1] = 123
args[2] = "Hello World" 
*/

class ArrayEx16 {
	public static void main(String[] args) {
		System.out.println("매개변수의 개수:"+args.length);

		for(int i=0;i< args.length;i++) {
			System.out.println("args[" + i + "] = \""+ args[i] + "\"");
		}
	}
}

c:\jdk1.8\work\ch5>java ArrayEx16 abc 123 "Hello World"

  • 매개변수 사이에 공백이 있는경우 “ “ 큰따옴표로 감싸주어야 함.
  • 커맨드 라인에서 숫자를 입력해도 문자열로 처리

3. 다차원 배열


3.1 2차원 배열의 선언과 인덱스

1차원 배열과 같지만 괄호[ ]가 하나 더 들어감.

선언 방법선언 예시
타입[][] 변수이름;int[][] scores;
타입 변수이름[][];int scores[][];
타입[] 변수이름[];int[] score[];

int[][] scores = new int[4][3]; → 4행 3열의 배열이 만들어짐.

intintint
intintint
intintint
intintint

2차원 배열의 인덱스
배열이름[행 index, 열 index]

int[0][0]int[0][1]int[0][2]
int[1][0]int[1][1]int[1][2]
int[2][0]int[2][1]int[2][2]
int[3][0]int[3][1]int[3][2]

3.2 2차원 배열의 초기화

int[][] arr = new int[][]{{1, 2, 3},{4, 5, 6}};
int[][] arr = {{1, 2, 3},{4, 5, 6}}; // new int[][] 생략 가능

// 가독성 위해
int[][] arr = {
	{1, 2, 3}, 
	{4, 5, 6}
};
class ArrayEx18 {
	public static void main(String[] args) {
		 int[][] score = {
							{ 100, 100, 100}
							, { 20, 20, 20}
							, { 30, 30, 30}
							, { 40, 40, 40}
						};
		int sum = 0;

		for(int i=0;i < score.length;i++) {
			for(int j=0;j < score[i].length;j++) {
				System.out.printf("score[%d][%d]=%d%n", i, j, score[i][j]);
			}
		}

		for (int[] tmp : score) { 
			 for (int i : tmp) { 
				sum += i;
			 } 
		} 

		System.out.println("sum="+sum);
	}
}

3.3 가변 배열

2차원 이상의 배열을 ‘배열의 배열’ 의 형태로 처리한다는 사실을 이용, 열의 길이를 각자 지정해줌.

int[][] score = new int[5][];
score[0] = new int[4];
score[1] = new int[3];
score[2] = new int[2];
score[3] = new int[2];
score[4] = new int[3];

int[][] score={
                 {100,100,100,100}
               ,	{20,20,20}
               ,	{30,30}
               ,	{40,40}
               ,	{50,50,50}     
};

3.4 다차원 배열의 활용

좌표에 X표하기

import java.util.*;

class MultiArrEx1 {
	public static void main(String[] args) {
		final int SIZE = 10;
		int x = 0, y = 0;

		char[][] board = new char[SIZE][SIZE];
		byte[][] shipBoard = {
		  //  1  2  3  4  5  6  7  8  9
			{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1
			{ 1, 1, 1, 1, 0, 0, 1, 0, 0 }, // 2
			{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 3
			{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 4
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 5
			{ 1, 1, 0, 1, 0, 0, 0, 0, 0 }, // 6
			{ 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // 7
			{ 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // 8
			{ 0, 0, 0, 0, 0, 1, 1, 1, 0 }, // 9
		};

	     // 0행에 행번호를, 0열에 열번호를 저장한다. 
		for(int i=1;i<SIZE;i++)
			board[0][i] = board[i][0] = (char)(i+'0');

		Scanner scanner = new Scanner(System.in);

		while(true) {
			System.out.printf("좌표를 입력하세요.(종료는 00)>");
			String input = scanner.nextLine(); // 화면입력받은 내용을 tmp에 저장

			if(input.length()==2) {   // 두 글자를 입력한 경우
				x = input.charAt(0) - '0';  // 문자를 숫자로 변환
				y = input.charAt(1) - '0';

				if(x==0 && y==0) // x와 y가 모두 0인 경우 종료
					break; 
			} 
			
			if(input.length()!=2 || x <= 0 || x >= SIZE || y <= 0 || y >= SIZE){
				System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
				continue;
			}

			// shipBoard[x-1][y-1]의 값이 1이면, 'O'을 board[x][y]에 저장한다.  
			board[x][y] = shipBoard[x-1][y-1]==1 ? 'O' : 'X';  

			// 배열 board의 내용을 화면에 출력한다.
			for(int i=0;i<SIZE;i++) {
				System.out.println(board[i]); // board[i]는 1차원 배열
			}
			System.out.println();
		}
	} // main의 끝
}

빙고

import java.util.*;

class MultiArrEx2 {
	public static void main(String[] args) {
		final int SIZE = 5;
		int x = 0 , y = 0;
		int num = 0;

		int[][] bingo = new int[SIZE][SIZE];
		Scanner scanner = new Scanner(System.in);

		// 배열의 모든 요소를 1부터 SIZE*SIZE까지의 숫자로 초기화
		for(int i=0;i<SIZE;i++) {
			for(int j=0;j<SIZE;j++) {
				bingo[i][j] = i*SIZE + j + 1;
			}
		}

		// 배열에 저장된 값을 뒤섞는다.(shuffle)
		for(int i=0;i<SIZE;i++) {
			for(int j=0;j<SIZE;j++) {
				x = (int)(Math.random() * SIZE);
				y = (int)(Math.random() * SIZE);

				// bingo[i][j]와 임의로 선택된 값(bingo[x][y])을 바꾼다.
				int tmp =  bingo[i][j];
				bingo[i][j] = bingo[x][y];
				bingo[x][y] = tmp;
			}
		}

		do {
			for(int i=0;i<SIZE;i++) {
				for(int j=0;j<SIZE;j++)
					System.out.printf("%2d ", bingo[i][j]);	
				System.out.println();
			}
			System.out.println();
		
			System.out.printf("1~%d의 숫자를 입력하세요.(종료:0)>", SIZE*SIZE);
			String tmp = scanner.nextLine(); // 화면에서 입력받은 내용을 tmp에 저장
			num = Integer.parseInt(tmp);     // 입력받은 문자열(tmp)를 숫자로 변환

			// 입력받은 숫자와 같은 숫자가 저장된 요소를 찾아서 0을 저장
			outer:
			for(int i=0;i<SIZE;i++) {
				for(int j=0;j<SIZE;j++) {
					if(bingo[i][j]==num) {
						bingo[i][j] = 0;
						break outer; // 2중 반복문을 벗어난다.
					}
				}
			}
		} while(num!=0); 
	} // main의 끝
}

행렬의 곱셈

class MultiArrEx3 {
	public static void main(String[] args) {
		int[][] m1 = {
			{1, 2, 3},
			{4, 5, 6}
		};

		int[][] m2 = {
			{1, 2},
			{3, 4},
			{5, 6}
		};

		final int ROW    = m1.length;      // m1의 행길이
		final int COL    = m2[0].length;  // m2의 열길이
		final int M2_ROW = m2.length;	    // m2의 행길이

		int[][] m3 = new int[ROW][COL];

	   // 행렬곱 m1 x m2의 결과를 m3에 저장
		for(int i=0;i<ROW;i++)
			for(int j=0;j<COL;j++)
				for(int k=0;k<M2_ROW;k++)
					m3[i][j] += m1[i][k] * m2[k][j]; 

	   // 행렬 m3를 출력 
		for(int i=0;i<ROW;i++) {
			for(int j=0;j<COL;j++) {
				System.out.printf("%3d ", m3[i][j]);
			}
			System.out.println();
		}
	} // main의 끝
}

단어 맞추기

import java.util.*;

class  MultiArrEx4{
	public static void main(String[] args) {
		String[][] words = {
			{"chair","의자"},			// words[0][0], words[0][1]
			{"computer","컴퓨터"},	// words[1][0], words[1][1]
			{"integer","정수"}		// words[2][0], words[2][1]
		};

		Scanner scanner = new Scanner(System.in);

		for(int i=0;i<words.length;i++) {
			System.out.printf("Q%d. %s의 뜻은?", i+1, words[i][0]);

			String tmp = scanner.nextLine();

			if(tmp.equals(words[i][1])) {
				System.out.printf("정답입니다.%n%n");
			} else {
			   System.out.printf("틀렸습니다. 정답은 %s입니다.%n%n",words[i][1]);
			}
		} // for
	} // main의 끝
}

0개의 댓글