15-java - 배열(수업내용)

jin·2022년 5월 13일
0

이하 강의 내용 정리

배열(array)

배열 개념

  1. "같은 종류"의 데이터를 "여러개" 저장하기 위한 기술

  2. 선언법

 int[] array = new int[방의 개수];  // [] 대괄호 위치는 앞 뒤 어디든상관없다.
 int array[] = new int[방의 개수];
  1. 인덱스(index)
    0부터 시작하는 방번호(index)가 부여된다.
    방번호는 순차적으로 1씩 증가한다.
    예) int array[] = new int[5];
    방번호는 0,1,2,3,4
  2. 배열의 초기화
    배열은 null 을 사용한다.
  3. 배열의 각각의 변수의 초기화
    배열은 자동으로 변수에 0 을 저장한다.
  4. 사용법
    각각의 방번호를 이용해서 값을저장한다.
    array[0] = 1;
    array[1] = 2;
  5. 없는 방을 사용하면 에러가 발생한다.
    array[10] = 10;

배열 작성 방법 1

// 1.일반변수의 값저장방법. 
int num = 0;
num = 10;
System.out.println("num = " + num);
System.out.println("------------------------------");

// 2. 배열
int[] array = null; // 배열은 null을 0 대신 사용한다.
array = new int[5]; // 변수 5개가 생겨나고 기본값 0 이 저장된다. (자동으로 저장된다.)

System.out.println(array[0]);   // 0
System.out.println(array[1]);	// 0
System.out.println(array[2]);	// 0
System.out.println(array[3]);	// 0
System.out.println(array[4]);	// 0
System.out.println("------------------------------");

for(int i = 0; i<5; i++) {
	System.out.println(array[i]);//array 초기값 지정을 안했으므로 i 번째 array 값은 0이 나옴 
}
/*	
	Integer a = null; // 참조 자료형 -> null값(기본값)
	System.out.println(a);
	int arr[] = new int[3]; -> 기본자료형의 배열값 --> 그냥 출력시 0
	int arr[] = null;은 그냥 null값 --> 바로 윗 라인과 다름, --> 그냥 출력시 null
	String arr[] = new String[3];
	System.out.println(arr[0]);
*/

개인적인 추가부분은 예시 아래에 여러줄 주석으로 남겼다. 기억은 해두자.

배열 작성 방법 2

//	1. 배열 사용법 (1)
int[] array = new int[3];
array[0] = 10;
array[1] = 20;
array[2] = 30;

for (int i=0; i < array.length; i++) {
	System.out.println(array[i]);
}
System.out.println("-----------------------------");
//	2. 배열 사용법(2) : 아래는 축약형으로 위와 동일한 결과이다
int temp[] = { 10, 20, 30 };
for (int i = 0; i< 3; i++) {
	System.out.println(temp[i]);
}
System.out.println("-----------------------------");
//temp = { 40, 50, 60 }; // 이렇게 한번더 축약형을 쓰면 에러발생	
//temp = new int[]{ 40, 50, 60 }; // 기존 temp 식별자에 새 배열 주소를 만듦, 기존 배열 주소는 사라짐
temp[0] = 40; // 기존 배열 temp[0]번째 값 변경
temp[1] = 50;
temp[2] =60;
for (int i = 0; i< 3; i++) {
	System.out.println(temp[i]);
}

배열 기본 문제 1

[문제1] 10부터 50까지 array 배열에 저장후 배열안의 모든값을 출력한다.
[예] 10 20 30 40 50

[문제2] array 배열안의 모든값을 출력한다.
[예] 150

int[] array = new int[5];	
int sum = 0;

for (int i=0; i < array.length; i++) {
	array[i] = (i+1)*10;
	System.out.print(array[i] +" ");
		sum += array[i];
}

배열 기본 문제 2

10,20,30,40,50을 가진 배열이 있다.

[문제1] 4의 배수만 출력한다.
[예] 20 40

[문제2] 4의 배수의 합을 출력한다.
[예] 60

[문제3] 4의 배수의 개수를 출력한다.
[예] 2

int[] array = {10,20,30,40,50};
int sum = 0;
int count = 0;
System.out.print("4의 배수 : ");
for (int i=0; i < array.length; i++) {
	if (array[i] % 4 == 0) {
		sum += array[i];
		count +=1;
		System.out.print( array[i]+" ");
	}
}
System.out.println();
System.out.println("4의 배수 합 : "+sum);
System.out.println("4의 배수 개수 : " + count);

나는 for문 한번으로 해결된다면 최대한 활용해봤다.

배열 기본 문제 3

[문제1]
array1배열 과 array2배열의 각자리별 합을 temp1에저장
temp1 = {10 + 5 , 20 + 8, 30 + 54, 40 + 32, 50 + 1};

[문제2]
array1배열 과 array2배열의 각자리별 차를 temp2에저장
temp2 = {10 - 5 , 20 - 8, 30 - 54, 40 - 32, 50 - 1};

int array1[] = { 10, 20, 30, 40, 50 };
int array2[] = { 5, 8, 54, 32, 1 };

int temp1[] = new int[5];
int temp2[] = new int[5];

for (int i = 0; i < temp1.length; i++) {
	temp1[i] = array1[i] + array2[i];
	System.out.print(temp1[i] + " ");
}
System.out.println();
for (int i = 0; i < temp2.length; i++) {
	temp2[i] =array1[i] - array2[i];
	System.out.print(temp2[i] + " ");
}

배열 기본 문제 4

학생번호들 = { 1001, 1002, 1003, 1004, 1005 };
학생번호에 대응되는 점수들 = { 87, 11, 45, 98, 23 };
[문제] 학번을 입력받아 성적 출력
[정답] 학번 입력 : 1003 성적 : 45점

[추가조건]
지금은 한번만 입력하면 나오고 끝나지만,
내가 원할때까지 확인하고 -1000을 입력하면종료.

import java.util.Scanner;

Scanner sc = new Scanner(System.in);
		
int[] numberList = { 1001, 1002, 1003, 1004, 1005 };
int[] scoreList = { 87, 11, 45, 98, 23 };
int index = -1;
System.out.println("-1000 입력시 종료");

while (true) {
	System.out.print("학번 입력 : ");
	int inputNumber = sc.nextInt();
	if (inputNumber == -1000) {
		System.out.println("종료");
		break;
	} else {
		for (int i = 0; i < numberList.length; i++) {
			if (numberList[i] == inputNumber) {
				index = i;
			}
		}
		System.out.println("점수 : "+scoreList[index]);
	}
}
sc.close();

배열 거꾸로 저장하기 문제

a = { 1,2,3,4,5 };

[문제] a 배열의 값을 b 배열에 하나씩 저장하는데 순서를 거꾸로 저장
[예] b = {5,4,3,2,1};

int a[] = { 1, 2, 3, 4, 5 };
int b[] = new int[5];
int j =0;
for (int i = a.length-1; i >= 0 ; i--) {
	b[j] = a[i];
	j += 1;
}

for (int i = 0; i < b.length; i++) {
	System.out.print(b[i] + " ");
}

해당 문제는 배열의 인덱스값을 거꾸로 찾아야한다. 그리고 복사할 배열의 인덱스에 관한 변수를 선언하고 0번째부터 값을 추가시키며 증가한다.

배열 삭제 원리 문제

[문제]
아래배열 a 의 안에 있는 값을 하나 입력받는다.
b배열안에 위에서 입력한 값을 제외하고 복사한다.

[예] 30 ==> b[] = {10,20,40,50,0};

[문제]
아래 배열 c는 번호와 값이 한쌍인 배열이다.
번호를 하나를 입력받고 c배열에 있는 번호이면,
그번호와 값만 제외하고 d배열에 복사한다.

[예] 1002 ==> d[] = {1001, 40, 1003, 70 , 0, 0};

int a[] = { 10, 20, 30, 40, 50 };
int b[] = { 0, 0, 0, 0, 0 };

int x = 30; // 삭제할 값 가정
int index = 0;

for (int i = 0; i < a.length; i++) {
	// 삭제할 값과 a의 i번째 위치가 같지 않을때 b배열에 넣기
	if (x != a[i]) {
		b[index] = a[i];
		index += 1;
	}
}
for (int i = 0; i < b.length; i++) {
	System.out.print(b[i] + " ");
}
System.out.println();
int c[] = { 1001, 40, 1002, 65, 1003, 70 };
int d[] = { 0, 0, 0, 0, 0, 0 };
int z = 1001;
index = 0;

for (int i = 0; i < c.length; i+=2) {
	// 네자리수 옆의 두자리수도 같이 지워야함
	// c[i] -> c의 i번째 값, 2칸씩 증가해야함
	// z값이 c 배열값에 해당이 안될경우 경우 c배열들 d로 복사
	if (z != c[i]) {
		d[index] = c[i];
		d[index+1] = c[i+1];
		index +=2;
	}
}
for (int i = 0; i < d.length; i++) {
	System.out.print(d[i] + " ");
}

삭제원리 문제는 첫번째 값을 뒤로 미루는건 단순히 인덱스값을 해당 값 위치에서 1 증가시켜줬으면 됐으나 두번째 문제에서 생각을 해야했다.
네자리수와 두자리수를 한 쌍으로 보고 네자리수를 삭제할 경우 쌍이 되는 두자리 수를 삭제해야하는데 단순하게 인덱스 증가값을 2로 줬으면 됐었던 문제였다.
하지만 나는 1씩 증가하며 별도의 다른 변수 없이 쌍으로 삭제 가능하지 않을까 생각해봤고 결국 한칸씩 뒤로 밀리는건 두자리 수 부터 밀려서 망했다.
인덱스 주의하자.

배열 채팅원리 문제

[문제1]
array1 배열의 값들을 앞으로 한칸씩 당기고 맨뒤에 a의 값을 저장한다.
[예] array1 = {20,30,40,50,90};

[문제2] array2 의 배열을 뒤로 하나씩 밀어낸후 맨 앞에 b의 값을 저장한다.
[예] array2 = {60,10,20,30,40};

int array1[] = { 10, 20, 30, 40, 50 };
int a = 90;

for (int i = 0; i < array1.length; i++) {
	if (i < (array1.length -1) ) {
		array1[i] = array1[i+1];
	} else {
		array1[i] = a;
	}
}

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

int array2[] = { 10, 20, 30, 40, 50 };
int b = 60;
// index값이 거꾸로 가야함 --> 4번째 값이 5번째 오게끔 --> 배열크기-1
int index = array2.length - 1;

for (int i = 0; i < array2.length-1; i++) { //기존 마지막 배열값이 밀렸기때문에 1번 덜 돌림 --> 배열크기 -1
	array2[index] = array2[index-1];
	index -= 1;
}
array2[0] = b;

for (int i = 0; i < array2.length; i++) {
	System.out.print(array2[i] + " ");
}

이 문제도 삭제원리 문제와 같이 첫번째는 인덱스값을 한칸씩 미뤄서 저장하면 됐었다.
문제는 두번째 문제로 배열에 대해 개념이 두루뭉실해서 오류를 범했다.
50이 삭제되고 60을 0번째 인덱스에 넣어야하는데, 배열의 크기가 5이므로 최대 인덱스값은 4가 된다. 이 인덱스값에서 감소하며 저장했어야하는데 0번 값에 60을 넣고 1번 인덱스를 뒤쪽으로 이동하니 같은 값이 저장저장저장 반복의 과정이라 올바른 답이 나오지 않았다.
이때 여러 방법을 생각하며 여러번 징하게 본 에러

uncaught exception ArrayIndexOutOfBoundsException

이 에러는 인덱스가 배열의 크기보다 크거나 음수일때 발생한다.
예시)

for (int i = 0; i <= b.length; i++) { 
	오류! b배열의 크기는 5이니 4까지임. 
	조건식을 크거나같다<=로 하려면 length-1을 해주거나 비교연산자를 바꿔야함
	해당 배열 인덱스 크기보다 크므로 에러
}

배열 사탕 나눠주기 문제

[사탕나눠주기2]

아래 배열은 각병에 들어있는 사탕의 양이다.
사탕의 종류는 전부 다르고 한사람당 한병에서 25개씩 나눠줄려고 하고있다.
남은사탕은 옆으로 옮겨서 다음 사람한테 나눠줄수있다.
나눠줄수있는 사람수를
사람수 배열에 저장하시오.

candy[] = { 97, 53, 36, 22 } - 각 종류의 사탕 수
people[] = { 0, 0, 0, 0 } - 사람 수

int candy[] = { 97, 53, 36, 22 }; // 각 종류의 사탕 수
int people[] = { 0, 0, 0, 0 }; // 사람 수

System.out.println("처음 사탕 수");
for (int i = 0; i < people.length; i++) {
	System.out.print(candy[i] + " ");
}
System.out.println("\n");

int candyIndex = 1;
for (int i = 0; i < candy.length; i++) {
	if (candyIndex <= candy.length-1) {
		System.out.println( (i +1) +" 번째 나눠주고 남은 사탕 수 : " + candy[i]%25);
		candy[candyIndex] += candy[i]%25;
		System.out.println( "다음 사탕 수 : " + candy[candyIndex]);
	}
	people[i] = candy[i]/25;
	candyIndex++;
}
System.out.println("\n사탕 수");
for (int i = 0; i < people.length; i++) {
	System.out.print(candy[i] + " ");
}
System.out.println();
System.out.println("\n나눠준 사람 수");
for (int i = 0; i < people.length; i++) {
	System.out.print(people[i] + " ");
}

위의 삭제원리 첫번째 문제 응용이다. 나는 사탕에 대한 인덱스 값을 주고 반복문 실행때 마다 증가값을 주어 if문으로 조건에 맞는 값만 들어가도록 했다.

덤. 좀 고민되는게 보통 진행방식이 기본이론 - 프로젝트 - 알고리즘 순이다
기본이론 - 응용 - 심화 단계인데 이걸 다 진행하고 포스팅을 해야할지 기본 이론만 하고 해야할지 고민 중인데, 아직 확실하게 답을 내리진 못했다. 좀 더 해보고 알맞는 방식을 찾아보자...

덤2. 해당 챕터는 인덱스에 대한 접근때문에 호다닥 진도 뺄 줄 알았던게 이틀동안 붙잡고 있었다. 그런데 그 이틀이 5/12일 시험과 발표 ,5/13일 반복문 팀 과제 때문에 약간 애매한 이틀이지 않나 싶기도 하고... 암튼 인덱스와 친해지자....

5/16 추가 - 배열 선언방식 의문점 해결

위에서도 언급했지만 1차원 배열 선언에는 두가지 방법이 있다.

int[] arr1 = new int[5];
int arr2[] = new int[5];

이렇게 타입에 배열[]을 붙이냐, 배열 이름에 배열[]을 붙이냐 두 가지로 나뉘는데 차이점이 궁금했다.
5/15일에 책 내용 정리하면서도 선언 방법만 나와있지 이에 대한 언급이 없었다.
그래서 오늘 학원와서 구글링을 해보니 TCP School에서 짧게 arr1의 방법을 사용하는 것이 좋다고 언급이 됐다.
하지만 이것으로 해답은 또 명확하지 않았고 선생님 찬스를 썼다.
그 결과, arr2의 선언 방식은 java에서만 가능하다고. 다른 언어에서 사용하면 에러라는 것이다. 모닝부터 선생님 바짓가랑이를 붙잡은 결과 의문은 해소됐고... 허허허 자바 언어 개발자는 왜 두번째 방법을 만들었을까...
암튼 나중에 다른 언어를 배울수도 있는거고 맞딱뜨릴수도 있는 거고 사람 앞일은 어떻게 될지 모르니 첫번째 방법으로 사용하자...

5/22 추가
책에서 배열에 대한 설명 정리

0개의 댓글