1. 배열(array)
1.1 배열의 선언과 생성
1.1.1 배열의 생성
타입[] 변수이름; // 배열을 선언(배열을 다루기 위한 참조변수 선언) 변수이름 = new 타입[길이]; .. 배열을 생성(실제 저장공간을 생성)
1.1.2 배열의 생성과정
- int[] score; → int형 배열 참조변수 score를 선언. 데이터를 저장할 수 있는 공간은 아직 마련되지 않음.score
- score = new int[5]; → 연산자 ‘new’에 의해서 메모리의 빈 공간에 5개의 데이터를 저장할 수 있는 공간이 마련된다.
score score[0] score[1] score[2] score[3] score[4]
0x100
그리고 각 배열요소는 자동적으로 int의 기본값(default)인 0으로 초기화된다.
score score[0] score[1] score[2] score[3] score[4]
0 | 0 | 0 | 0 | 0 |
0x100
끝으로 대입 연산자’=’에 의해 배열의 주소가 int형 배열 참조변수 score에 저장된다.
score score[0] score[1] score[2] score[3] score[4]
0x100 |
0 | 0 | 0 | 0 | 0 |
0x100
1.1.3 배열의 길이 변경
- 더 큰 배열을 새로 생성
- 기존 배열의 내용을 새로운 배열에 복사
1.2 배열의 초기화
int[] score = new int[5]; score[0] = 50; score[1] = 60; score[2] = 70; score[3] = 80; score[4] = 90;
배열의 길이가 큰 경우에는 for문을 사용하는 것이 좋다.
int[] score = new int[5]; for(int i = 0; i < score.length; i++) score[i] = i * 10 + 50;
for문으로 배열을 초기화하려면 저장하려는 값에 일정한 규칙이 있어야만 가능하다.
int[] score = new int[]{ 50, 60, 70, 80, 90}; // 배열의 생성과 초기화를 동시에
- [예제] 배열의 출력
import java.util.Arrays; public class _01_ArrayEx { 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,2,3,4,5,6,7,8,9,10, [5, 7, 7, 10, 10, 1, 1, 10, 7, 8] [100, 95, 80, 70, 60] [a, b, c, d] [I@6108b2d7 abcd
Arrays.toString(배열이름) : 배열의 모든 요소를 ‘[첫번째 요소, 두번째 요소, …]’와 같은 형식의 문자열로 만들어서 반환함.
int[] iArr3 = {100, 95, 80, 70, 60}; // 배열 iArr의 모든 요소를 출력한다. [100, 95, 80, 70, 60]이 출력된다. System.out.println(Arrays.toString(iArr));
→ 만일 iArr의 값을 바로 출력한다면? iArr은 참조변수니까 변수에 저장된 값, 즉 ‘배열의 주소’가 출력될 것으로 생각했겠지만 실제로는
‘타입@주소’의 형식으로 출력된다. ‘[I’는 1차원 int 배열이라는 의미이고, ‘@’ 뒤에 나오는 16진수는 배열의 주소인데 실제 주소가 아닌 내부 주소이다. 이 내용은 지금 진도와 맞지 않는 내용이므로 가볍게 참고만 하고, 배열을 가리키는 참조변수를 출력해봐야 별로 얻을 정보가 없다.
예외적으로 char 배열은 println 메서드로 출력하면 각 요소가 구분자없이 그대로 출력되는데, 이것은 println 메서드가 char 배열일 때만 이렇게 동작하도록 작성되었기 때문!
char[] chArr = {'a','b','c','d'}; System.out.println(chArr); // abcd가 출력된다.
1.3 배열의 복사
- 배열은 한번 생성하면 그 길이를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 내용을 복사해야한다. 배열을 복사하는 방법은 두 가지가 있는데, for문 이용과 System.arraycopy()가 있다.
- for문 이용
int[] arr = new int[5]; ... int[] tmp = new int[arr.length*2]; // 기존 배열보다 길이가 2배인 배열 생성 for(int i = 0; i < arr.length; i++) tmp[i] = arr[i]; // arr[i]의 값을 tmp[i]에 저장 arr = tmp; // 참조변수 arr이 새로운 배열을 가리키게 한다. // 1. 배열 arr의 길이인 arr.length의 값이 5이므로 길이가 10인 int 배열 tmp가 생성되고 // 배열 tmp의 각 요소는 int의 기본값인 0으로 초기화된다. int[] tmp = new int[arr.length*2]; int[] tmp = new int[10];
arr
0x100 |
tmp
0x200 |
arr[0] ~ arr[4]
1 | 2 | 3 | 4 | 5 |
0x100
tmp[0] ~ tmp[9]
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0x200
// 2. for문을 이용해서 배열 arr의 모든 요소에 저장된 값을 하나씩 배열 tmp에 복사한다. for(int i = 0; i < arr.length;i++) tmp[i] = arr[i];
arr
0x100 |
tmp
0x200 |
arr[0] ~ arr[4]
1 | 2 | 3 | 4 | 5 |
0x100
tmp[0] ~ tmp[9]
1 | 2 | 3 | 4 | 5 | 0 | 0 | 0 | 0 | 0 |
0x200
// 3. 참조변수 arr에 참조변수 tmp의 값을 저장한다. arr의 값은 0x100에서 0x200으로 바뀌고, arr은 배열 tmp를 가리키게 된다. arr = tmp; // 변수 tmp에 저장된 값을 변수 arr에 저장한다.
arr
0x200 |
tmp
0x200 |
arr[0] ~ arr[4]
1 | 2 | 3 | 4 | 5 |
0x100
tmp[0] ~ tmp[9]
1 | 2 | 3 | 4 | 5 | 0 | 0 | 0 | 0 | 0 |
0x200
→ 결국 참조변수 arr과 tmp는 같은 배열을 가리키게 된다. 즉 배열 arr과 배열 tmp는 이름만 다를 뿐 동일한 배열이다.
그리고 전에 arr이 가리키던 배열은 더 이상 사용할 수 없게 된다.
- [예제] 배열의 복사
public class _02_ArrayEx2 { 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("[변경전]"); 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("[변경후]"); System.out.println("arr.length:" + arr.length); for (int i = 0; i < arr.length; i++) System.out.println("arr[" + "]:" + arr[i]); } }
// 결과 [변경전] arr.length:5 arr[0]:1 arr[1]:2 arr[2]:3 arr[3]:4 arr[4]:5 [변경후] arr.length:10 arr[]:1 arr[]:2 arr[]:3 arr[]:4 arr[]:5 arr[]:0 arr[]:0 arr[]:0 arr[]:0 arr[]:0
- System.arraycopy()를 이용한 배열의 복사
- for문은 배열의 요소 하나하나에 접근해서 복사하지만, arraycopy()는 지정된 범위의 값들을 한 번에 통째로 복사함.→ 더 효율적이다
System.arraycopy(num, 0, newNum, 0, num.length); // -> num[0]에서 newNum[0]으로 num.length 개의 데이터를 복사
→ 복사하려는 배열의 위치가 적절하지 못하여 복사하려는 내용보다 여유 공간이 적으면 에러가 발생
- [예제] System.arraycopy()를 이용한 배열의 복사
public class _03_ArrayEx3 { 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); System.arraycopy(abc, 0, num, 6, 3); System.out.println(num); } }
1.4 배열의 활용
1.4.1 [예제] 총합과 평균
public class _04_SumAndAverage { 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); } }
// 결과 총점 : 478 평균 : 95.6
1.4.2 [예제] 최대값과 최소값
public class _05_MaxAndMin { 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]; } } System.out.println("최대값 :" + max); System.out.println("최소값 :" + min); } }
// 결과 최대값 :100 최소값 :33
1.4.3 [예제] 섞기(shuffle)
a) 카드 섞기
public class _06_Shuffle { 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; // numArr[0]과 numArr[n]의 값을 서로 바꾼다. } for (int i = 0; i < numArr.length; i++) { System.out.print(numArr[i]); } } }
// 결과 0123456789 3294680175
b) 로또 번호 추첨
public class _07_RandomValue { public static void main(String[] args) { int[] ball = new int[45]; // 45개의 정수값을 저장하기 위한 배열 생성. // 배열의 각 요소에 1~45의 값을 저장한다. for (int i = 0; i < ball.length; i++) ball[i] = i + 1; // ball[0]에 1이 저장된다. int temp = 0; // 두 값을 바꾸는데 사용할 임시변수 int j = 0; // 임의의 값을 얻어서 저장할 변수 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]); } }
ball[0] = 2 ball[1] = 17 ball[2] = 5 ball[3] = 43 ball[4] = 29 ball[5] = 11
1.4.4 [예제] 임의의 값으로 배열 채우기
- 배열을 연속적인 범위의 임의의 값을 채우는 방법
for (i = 0; i < arr.length; i++) { arr[i] = (int) (Math.random() * 5); // 0~4 범위의 임의의 값을 저장 }
- [예제]
import java.util.Arrays; public class _08_RandomValue { 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)); } }
// 결과 [-1, -1, 6, -1, -1, 6, 6, 11, 11, -4]
1.4.5 [예제] 정렬하기(sort)
- 버블정렬
public class _09_BubbleSort { 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)); // 0~9 } 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로 바꿈. } } if (!changed) break; // 자리바꿈이 없으면 반복문을 벗어난다. for (int k = 0; k < numArr.length; k++) System.out.print(numArr[k]); // 정렬된 결과를 출력한다. System.out.println(); } } }
// 결과 3642814310 3426143108 3241431068 2314310468 2133104468 1231034468 1210334468 1102334468 1012334468 0112334468
1.5.6 [예제] 빈도수 구하기
public class _10_Frequency { 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]); } } }
// 결과 7815898968 0의 개수 : 0 1의 개수 : 1 2의 개수 : 0 3의 개수 : 0 4의 개수 : 0 5의 개수 : 1 6의 개수 : 1 7의 개수 : 1 8의 개수 : 4 9의 개수 : 2
2. String 배열
2.1 String 배열의 선언과 생성
String[] name = new String[3]; // 3개의 문자열을 담을 수 있는 배열을 생성
2.2 String 배열의 초기화
String[] name = new String[3]; // case 1 name[0] = "Park"; nmae[1] = "Ha" nmae[2] = "Kim"; // case 2 String[] name = new String[]{"Park", "Ha", "Kim"}; String[] name = {"Park", "Ha", "Kim"}; // new String[] 생략 가능 // name name[0] name[1] name[2] // 0x100 -----> "Park" "Ha" "Kim" // 0x100 // 특별히 String 클래스만 "Park"과 같이 큰따옴표만으로 간략히 표현하는 것이 허용되지만 // 원래의 String은 클래스이므로 case 3 처럼 new 연산자를 통해 객체를 생성해야 한다. // case 3 String[] name = new String[3]; name[0] = new String("Park"); nmae[1] = new String("Ha"); nmae[2] = new String("Kim"); // name name[0] name[1] name[2] // 0x100 -----> 0x200 0x300 0x400 // 0x100 ↓ ↓ ↓ // "Park" "Ha" "Kim" // 0x200 0x300 0x400 // 배열에 실제 객체가 아닌 객체의 주소가 저장되어 있음. 이처럼 기본형 배열이 아닌 경우, // 즉 참조형 배열의 경우 배열에 저장되는 것은 객체의 주소이다. // 참조형 배열을 객체 배열이라고도 한다. // 참조형 변수를 간단히 참조변수라고도 하며, 모든 참조형 변수에는 객체가 메모리에 저장된 주소인 // 4 byte의 정수값(0x0 ~ 0xffffffff) 또는 null이 저장된다.
2.2.1 [예제] String 배열과 for 문
public class _11_StringArrayEx1 { public static void main(String[] args) { String[] names = new String[]{"Park", "Ha", "Kim"}; 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); } }
// 결과 names[0]:Park names[1]:Ha names[2]:Kim tmp:Kim Yu Ha Kim
2.2.2 [예제] 16진수를 2진수로 변환
public class _12_HexToBinary { public static void main(String[] args) { char[] hex = {'C', 'A', 'F', 'E'}; String[] binary = {"0000", "0001", "0010", "0011" , "0100", "0101", "0110", "0111" , "1000", "1001", "1010", "1011" , "1100", "1101", "1110", "1111"}; String result = ""; for (int i = 0; i < hex.length; i++) { if (hex[i] >= '0' && hex[i] <= '9') { result += binary[hex[i] - '0']; // '8'-'0'의 결과는 8 } else { result += binary[hex[i] - 'A' + 10]; // 'C'-'A'의 결과는 2 } } System.out.println("hex:" + new String(hex)); System.out.println("binary:" + result); } }
// 결과 hex:CAFE binary:1100101011111110
2.3 char 배열과 String 클래스
→ 변경 가능한 문자열을 다루려면, StringBuffer 클래스를 사용하면 된다.
2.3.1 String 클래스의 주요 메서드
메서드 | 설명 |
---|---|
char charAt(int index) | 문자열에서 해당 위치(index)에 있는 문자를 반환한다. |
int length() | 문자열의 길이를 반환한다. |
String substring(int from, int to) | 문자열에서 해당 범위(from~to)에 있는 문자열을 반환한다. (to는 범위에 포함되지 않음) |
boolean equals(Object obj) | 문자열의 내용이 obj와 같은지 확인한다. 같으면 결과는 true, 다르면 false가 된다. |
char[] toCharArray() | 문자열을 문자배열(char[])로 변환해서 반환 |
2.3.2 [예제] char 배열과 String 클래스의 변환
public class _13_CharToString { public static void main(String[] args) { String src = "ABCDE"; for (int i = 0; i < src.length(); i++) { char ch = src.charAt(i); // src의 i번째 문자를 ch에 저장 System.out.println("src.charAt(" + i + "):" + ch); } } }
// 결과 src.charAt(0):A src.charAt(1):B src.charAt(2):C src.charAt(3):D src.charAt(4):E
2.3.3 [예제] 문자열(String)을 모르스(morse) 부호로 변환
public class _14_StringToMorse { public static void main(String[] args) { String source = "SOSHELP"; // 1A 2Bb 3C 4D 5E 6F 7G 8H 9I 10J // 11K 12L 13M 14N 15O 16P 17Q 18R 19S 20T // 21U 22V 23W 24X 25Y 26Z String[] morse = {".-", "-...", "-.-.", "-..", "." , "..-.", "--.", "....", "..", ".---" , "-.-", ".-..", "--", "-.", "---" , ".--.", "--.-", ".-.", "...", "-" , "..-", "...-", ".--", "-..-", "-.--" , "--.."}; String result = ""; for (int i = 0; i < source.length(); i++) { result += morse[source.charAt(i) - 'A']; } System.out.println("source:" + source); System.out.println("morse:" + result); } }
// 결과 source:SOSHELP morse:...---.........-...--.
2.4 커맨드 라인을 통해 입력받기 → (맥에서 어떻게 하는지 모르겠다)
- Scanner 클래스의 nextLine() 외에도 화면을 통해 사용자로부터 값을 입력받을 수 있는 방법→ 커맨드라인 이용하기
public class _15_CommandLine { public static void main(String[] args) { if (args != null) { System.out.println("매개변수의 개수:" + args.length); for (int i = 0; i < args.length; i++) { System.out.println("args[" + i + "] = \"" + args[i] + "\""); } } } }
// 결과 매개변수의 개수:0
3. 다차원 배열
3.1 2차원 배열은 선언과 인덱스
- 2차원 배열의 선언
선언 방법 | 선언 예 |
---|---|
타입[][] 변수이름; | in[][] score; |
타입 변수이름[][]; | int score[][]; |
타입[] 변수이름[]; | int[] score[]; |
// 2차원 배열은 주로 테이블 형태의 데이터를 담는데 사용된다. int[][] score = new int[4][3]; // 4행 3열의 2차원 배열을 생성하는 방법
3.2 2차원 배열의 초기화
- 2차원 배열도 괄호{}를 사용해서 생성과 초기화를 동시해 할 수 있다.다만, 1차원 배열보다 괄호{}를 한 번 더 써서 행별로 구분한다.
int[][] arr = new int[][]{{1, 2, 3}, {4, 5, 6}}; int[][] arr = { {1, 2, 3}, {4, 5, 6} }; // new int[][]가 생략
- [예제] 2차원 배열의 구성
public class _16_2D_Array { 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); } }
// 결과 score[0][0]=100 score[0][1]=100 score[0][2]=100 score[1][0]=20 score[1][1]=20 score[1][2]=20 score[2][0]=30 score[2][1]=30 score[2][2]=30 score[3][0]=40 score[3][1]=40 score[3][2]=40 sum=570
- [예제] 과목별 총점 계산
public class _17_SumAndAvg { public static void main(String[] args) { int[][] score = {{100, 100, 100} , {20, 20, 20} , {30, 30, 30} , {40, 40, 40} , {50, 50, 50} }; // 과목별 총점 int korTotal = 0, engTotal = 0, mathTotal = 0; System.out.println("번호 국어 영어 수학 총점 평균"); System.out.println("============================="); for (int i = 0; i < score.length; i++) { int sum = 0; // 개인별 총점 float avg = 0.0f; // 개인별 평균 korTotal += score[i][0]; engTotal += score[i][1]; mathTotal += score[i][2]; System.out.printf("%3d", i + 1); for (int j = 0; j < score[i].length; j++) { sum += score[i][j]; System.out.printf("%5d", score[i][j]); } avg = sum / (float) score[i].length; // 평균계산 System.out.printf("%5d %5.1f%n", sum, avg); } System.out.println("============================="); System.out.printf("총점: %3d %4d %4d%n", korTotal, engTotal, mathTotal); } }
// 결과 번호 국어 영어 수학 총점 평균 ============================= 1 100 100 100 300 100.0 2 20 20 20 60 20.0 3 30 30 30 90 30.0 4 40 40 40 120 40.0 5 50 50 50 150 50.0 ============================= 총점: 240 240 240
3.3 가변 배열
- 자바에서는 2차원 이상의 배열을 ‘배열의 배열’의 형태로 처리함.→다차원 배열을 생성할 때 전체 배열 차수 중 마지막 차수의 길이를 지정하지 않고, 추후에 각기 다른 길이의 배열을 생성하여 보다 유동적인 가변 배열을 구성 가능
// 예시 - 5 x 3 길이의 2차원 배열 score을 생성하는 코드 int[][] score = new int[5][3]; // 5행 3열의 2차원 배열 생성 // 위 코드를 다음과 같이 표현할 수 있음. int[][] score = new int[5][]; // 두 번째 차원의 길이는 지정하지 않음. score[0] = new int[3]; score[1] = new int[3]; score[2] = new int[3]; score[3] = new int[3]; score[4] = new int[3]; // 첫 번째 코드와 같이 2차원 배열을 생성하면 직사각형 테이블 형태의 고정적인 배열만 생성 가능 // 두 번째 코드와 같이 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];
3.4 다차원 배열의 활용
3.4.1 [예제] 좌표에 X표하기
- 입력한 2차원 좌표의 위치에 X를 표시
import java.util.Scanner; public class _18_MarkX { 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 }; // 1행에 행번호를, 1열에 열번호를 저장 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(); // 화면에 입력받은 내용을 input에 저장 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(); } } }
// 결과 좌표를 입력하세요. (종료는 00) >>11 123456789 1X 2 3 4 5 6 7 8 9 좌표를 입력하세요. (종료는 00) >>12 123456789 1XX 2 3 4 5 6 7 8 9 좌표를 입력하세요. (종료는 00) >>47 123456789 1XX 2O 3X 4O 5 6 7 8 9X 좌표를 입력하세요. (종료는 00) >>123 잘못된 입력입니다. 다시 입력해주세요. 좌표를 입력하세요. (종료는 00) >>-1 잘못된 입력입니다. 다시 입력해주세요. 좌표를 입력하세요. (종료는 00) >>00 Process finished with exit code 0
3.4.2 빙고
- 빙고판을 만들고 입력받은 숫자를 빙고판에서 지운다.
import java.util.Scanner; public class _19_Bingo { public static void main(String[] args) { final int SIZE = 5; int x = 0, y = 0, 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; // 1 2 3 4 5 // 6 7 8 9 10 // 11 12 13 14 15 // 16 17 18 19 20 // 21 22 23 24 25 // 배열에 저장된 값을 뒤섞는다.(shuffle) for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { x = (int) (Math.random() * SIZE); // 0~4 y = (int) (Math.random() * SIZE); // 0~4 // 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: // label을 설정하면 break 시 제어문에서 가까운 제어문이 아닌 원하는 위치의 제어문으로 break하거나 continue 가능 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); } }
// 결과 8 7 3 17 10 21 5 13 24 15 22 14 23 11 20 1 18 4 2 12 19 16 25 6 9 1~25의 숫자를 입력하세요. (종료 : 0) >> 7 8 0 3 17 10 21 5 13 24 15 22 14 23 11 20 1 18 4 2 12 19 16 25 6 9 1~25의 숫자를 입력하세요. (종료 : 0) >> 5 8 0 3 17 10 21 0 13 24 15 22 14 23 11 20 1 18 4 2 12 19 16 25 6 9 1~25의 숫자를 입력하세요. (종료 : 0) >> 14 8 0 3 17 10 21 0 13 24 15 22 0 23 11 20 1 18 4 2 12 19 16 25 6 9 1~25의 숫자를 입력하세요. (종료 : 0) >> 18 8 0 3 17 10 21 0 13 24 15 22 0 23 11 20 1 0 4 2 12 19 16 25 6 9 1~25의 숫자를 입력하세요. (종료 : 0) >> 16 8 0 3 17 10 21 0 13 24 15 22 0 23 11 20 1 0 4 2 12 19 0 25 6 9 1~25의 숫자를 입력하세요. (종료 : 0) >> 0 Process finished with exit code 0
3.4.3 행렬의 곱셈
- 두 행렬(matrix)을 곱한 결과를 출력
public class _20_Matrix { 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의 행 길이 = 2 final int COL = m2[0].length; // m2의 열 길이 = 2 final int M2_ROW = m2.length; // m2의 행 길이 = 3 int[][] m3 = new int[ROW][COL]; // 행렬곱 m1 x m2의 결과를 m3에 저장 for (int i = 0; i < ROW; i++) // 0~1 for (int j = 0; j < COL; j++) // 0~1 for (int k = 0; k < M2_ROW; k++) // 0~2 m3[i][j] += m1[i][k] * m2[k][j]; // 00 = 00 x 00 + 01 x 10 + 02 x 20 = 1 + 6 + 15 = 22 // 01 = 00 x 01 + 01 x 11 + 02 x 21 = 2 + 8 + 18 = 28 // 10 = 10 x 00 + 11 x 10 + 12 x 21 = 4 + 15 + 30 = 49 // 11 = 10 x 01 + 11 x 11 + 12 x 21 = 8 + 20 + 36 = 64 // 행렬 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(); } } }
// 결과 22 28 49 64
3.4.4 단어 맞추기
- 영어 단어를 보여주고, 뜻을 맞추는 게임
import java.util.Scanner; public class _21_WordGame { public static void main(String[] args) { String[][] words = { {"chair", "의자"}, // word[0][0], word[0][1] {"computer", "컴퓨터"}, // word[1][0], word[1][1] {"integer", "정수"} // word[2][0], word[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]); } } } }
// 결과 Q1. chair의 뜻은? >> 의자 정답입니다. Q2. computer의 뜻은? >> 컴터 틀렸습니다. 정답은 컴퓨터입니다. Q3. integer의 뜻은? >> 정수 정답입니다.
Uploaded by
N2T'Java > Java의 정석' 카테고리의 다른 글
객체지향 프로그래밍 𝐈 (0) | 2023.03.20 |
---|---|
[Java의 정석/3-2] 반복문 - for,while,do-while (0) | 2023.03.15 |
[Java의 정석/3-1] 조건문 - if, switch (0) | 2023.03.15 |
[Java의 정석/2-6] 그 외의 연산자 (0) | 2023.03.15 |
[Java의 정석/2-5] 논리 연산자 (1) | 2023.03.15 |