Ex27_Array

camicomi·2024년 1월 9일

package com.test.java;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Scanner;

public class Ex27_Array {

public static void main(String[] args) {
	
	
	// 배열, Array
	// - 자료구조 > 데이터 저장하는 물리적인 구조
	// - 데이터의 집합 > 변수들을 모아놓은 집합
	// - 같은 자료형을 저장하는 데이터의 집합 
	
	
	// m1();
	// m2();
	// m3();
	// m4();
	// m5();
	// m6();
	// m7();
	// m8();
	// m9();
	// m10();
	// m11();
	// m12();
	// m13(); // 배열 요소 삽입
	// m14(); // 배열 요소 삭제
	
	// m15();

	// m16();
	// m17();

	// m18();
	
	m19();
	
	
	
	
	// 정렬
	// - 크기 비교 후 > 재배치
	
	// 1. 오름차순
	// a. 숫자: 작은수 > 큰수
	// b. 문자열: 문자코드값 순
	// c. 날짜시간: 과거 > 미래
	
	// 2. 내림차순
	// a. 숫자: 큰수 > 작은수
	// b. 문자열 : 문자코드값 역순
	// c. 날짜시간: 미래 > 과거
	
	// 정렬 구현
	// 1. 직접 구현 > 정렬 알고리즘
	// 2. JDK 구현된 기능 (!) 
	
	
	// 버블 정렬 + swap 
	// swap > 두 공간의 데이터를 서로 바꾸는 작업 
	int a = 10;
	int b = 5;
	int temp; //  바꾸기 위한 빈컵 
	
	temp = a; // a 는 비어있다
	a = b; // b가 a로 옮겨지다
	b = temp; 
	
	System.out.println("a: " + a);
	System.out.println("b: " + b);
	
	// 1사이클 n - 1 개 비교
	// 2사이클 n - 2 개 비교
	// ...
	
	
	
	 
	int[] nums = { 5, 3, 1, 4, 2 };
	System.out.println(Arrays.toString(nums));
	
	
	for (int i=0; i<nums.length-1; i++) {// 사이클 (0, 1, 2 , 3)
	// 실제비교는여기부터
		for (int j=0; j<nums.length-1-i; j++) {
			
			// 오름차순
			if (nums[j] > nums[j+1]) {
				temp = nums[j];
				nums[j] = nums[j+1];
				nums[j+1] = temp;
				// 내림차순 if (nums[j] < nums[j+1]) {
			}
		}
	
	
	}
	System.out.println(Arrays.toString(nums));
	

	

// String name1 = "홍길동";
// String name2 = "아무개";

	// 문자코드값 비교 
	// 첫번째 글자 
	

// System.out.println(name1.compareTo(name2));

	// 두 글자의 문자코드값 차이 = 4361

// System.out.println((int)'홍'); // 문자코드값 문자가 뒤에 있을 수록 크니깐....
// System.out.println((int)'아'); // 우리는 어떤 것이 앞에 있는 글자이고 뒤에 있는 글자인 것인지 알면 된다...

	String[] names = { "홍길동", "아무개", "테스트", "유재석", "강아지", "고양이", "도깨비", "박명수", "조세호", "병아리" };
		
	
	for (int i=0; i<names.length-1; i++) {
		for (int j=0; j<names.length-1-i; j++) {
			
			// 오름차순, 가나다순정렬 
			if (names[j].compareTo(names[j+1])>0) {
				String temp2 = names[j];
				names[j] = names[j+1];
				names[j+1] = temp2;
				
				
			}
		}
	}
	
	System.out.println(Arrays.toString(names)); //날짜 시간도 가능
	
	
	
	// 49 번 for 문 (공백 for 문 + 별 for 문)
	// 52 번 문자코드로 만듦, 증가, 감소순 
	// 53 번 2 x 1 =  2      3 x 1 =  3      4 x 1 =  4      5 x 1 =  5  한줄을 먼저 찍은 것, 단이 먼저가 아닌......?  이중 for 문 2번 혹은 삼중 for 문 1번 사용 
	// 54 번 2 ~ 10 까지 돌리고 11/2, 11/3..... 나머지 0이면 약수??????????????????????
	// 57 번 단일 for 문이나 이중 for 문 사용
	// 59, 60 번 수열문제..
	
	
	
	
	
	
	
}// main

private static void m19() {
	
	
	int[][] nums = new int[5][5];
	
	int n = 1;
	
	// 2차원 배열 값 넣기
	for (int i=4; i>=0; i--) {
		for (int j=4; j>=0; j--) { // 4 3 2 1 0
			nums[i][j] = n; //접근하는 순서대로 1~ 넣음 
			n++;
		}
		System.out.println(
				);
	}
	
	for (int i=0; i<5; i++) {
		for (int j=0; j<5; j++) {
			System.out.printf("%3d", nums[i][j]);
			
		}
		
	}
	
	
}

private static void m18() {
	
	
	//****** 배열의 길이는 불변이다.
	// - 한번 만들어진 배열의 방은 더 늘리거나 삭제할 수 없다.
	
	//int[] kor = new int[300]; //정적 할당 , 최대수, 여유치 
	
	// 길이를 상수가 아닌 변수로 쓸 수 있으나, 이때도 X 	
	
	Scanner scan = new Scanner(System.in);
	
	System.out.print("학생수: ");
	
	int length = scan.nextInt();
	
	
	// int length = 3;
	int[] kor = new int[length]; // 동적 할당 , 사용자가 입력한 값으로 초기화시킬 수 있으므로 프로그램 동작중에 할당
	
	
	
	
	
}

private static void m17() {
	
	for (int i=0; i<10; i++) {
		
		System.out.println((int)(Math.random()* 100) + 1 ); // 원래 난수는 실수 , 
		
		
	}
	
	
	
	
}

private static void m16() {
	
	// 초기화 리스트
	int[] nums1 = { 10, 20, 30 };
	
	int[][] nums2 = 
		{
			{ 10, 20, 30 }, 
			{ 40, 50, 60 }
		}; 
	
	int[][][] nums3 = 
		{ 
			{ 
				{ 10, 20, 30 },
				{ 40, 50, 60 } 
			}, 
			{ 
				{ 70, 80, 90 },
				{100, 110, 120 }
			} 
		};
	
	// Jagged Array, 비정형 배열, 불규칙 배열
	int[][] nums4 = new int[3][4]; //안됨
	
	int[][] nums5 = 
		{ 
				{ 10, 20, 30 }, 
				{ 40, 50 }, 
				{ 60, 70, 80, 90 }
		};
	
	// Jagged Array 탐색
	for (int i=0; i<nums5.length; i++) {
		for (int j=0; j<nums5[i].length; j++) { // 고정이 아니므로 i
			System.out.printf("%5d", nums5[i][j]);
		}
		System.out.println();
	}
	
}

private static void m15() {
	
	// 배열의 차원
	// - 1차원 배열(인덱스를 하나 써서), 2차원 배열(y좌표부터) , 3차원 배열(겹쳐서..)..
	
	// 1차원 배열
	int[] nums1 = new int[3];
	nums1[0] = 10;
	nums1[1] = 20;
	nums1[2] = 30;
	
	
	System.out.println(Arrays.toString(nums1));
	
	
	// 2차원 배열
	
	int[][] nums2 = new int[2][3]; // 2차원 - 2, 3차원 - 3
	
	nums2[0][0] = 10;
	nums2[0][1] = 20;
	nums2[0][2] = 30; // 1층 끝
	
	nums2[1][0] = 10;
	nums2[1][1] = 20;
	nums2[1][2] = 30; // 2층 끝
	
	
	// nums2 자료형? > int[][]  > int 2차원배열이다
	// nums2[0] 자료형 ? > int[] > int 1차원 배열
	// nums2[0][0] 자료형? > int 
	nums2[0][1] = 20;
	System.out.println(nums2.length); // 2
	System.out.println(nums2[0].length); // 3
	System.out.println(nums2[0][0]); // 10 
	
	
	

	System.out.println(Arrays.toString(nums2));
	System.out.println(Arrays.deepToString(nums2));
	
	//System.out.println(nums2.length); // 2  겉에보이는구조때문에.
	
	
	//2차원 배열 탐색
	// 2중 for 문의 i와 j 
	
	for (int i=0; i<nums2.length; i++) { // 바깥
		for (int j=0; j<nums2[0].length; j++) { // 한바퀴를 돌면 한층
			System.out.println(nums2[i][j] + "\t");
		}
		System.out.println(); // 층이 바뀐다는 의미로 엔터
	}
	System.out.println();
	
	//3차원 배열
	int[][][] nums3 = new int[2][3][3];
	
	nums3[0][0][0] = 10;
	nums3[0][0][1] = 20;
	nums3[0][0][2] = 30;
	
	nums3[0][1][0] = 40;
	nums3[0][1][1] = 50;
	nums3[0][1][2] = 60;
	
	nums3[1][0][0] = 70;
	nums3[1][0][1] = 80;
	nums3[1][0][2] = 90;

	
	nums3[1][1][0] = 100;
	nums3[1][1][1] = 110;
	nums3[1][1][2] = 120;
	
	for (int i=0; i<nums3.length; i++) {
		for (int j=0; j<nums3[0].length; j++) {
			for (int k=0; k<nums3[0][0].length; k++) {
				
				System.out.printf("%5d", nums3[i][j][k]);
			}
			System.out.println();
		}
		System.out.println();
	}
			
	
	
	
	
}

private static void m14() {
	
	// 배열 요소 삭제(Deletion) 
	// 삽입의 역방향 (오른쪽에서 왼쪽으로 복사) 
	// 마지막 비워져 있으면 0으로 채워넣음
	// - Left Shift  > 왼쪽으로 한칸씩 이동했다. 
	// - *** 삭제 이후의 요소들이 인덱스가 변경된다. 
	
	int[] nums = { 1, 2, 3, 4, 5 };
	int index = 1;
	
	System.out.println(Arrays.toString(nums));
	
	// 필요한 인덱스 1, 2, 3
	
	for (int i=index; i<=nums.length-2; i++) {
		nums[i] = nums[i+1];
	}
	
	nums[nums.length-1] = 0; // 마지막 방
	
	System.out.println(Arrays.toString(nums));
	
	
}

private static void m13() {
	
	
	// 배열 조작
	// - 삽입, 삭제
	// - 비용 발생
	
	// 삽입 마지막요소 사라질수도 있음
	// 오른쪽부터 한칸씩 복사 후 안전한 상태에서 삽입
	
	// 중간에 삭제하면 앞으로 간다
	// 중요
	
	// 배열 삽입(Insertion)
	// - Right Shift > 오른쪽으로 한칸씩 이동했다. 
	// - *** 삽입 이후의 요소들이 인덱스가 변경된다. (값이 변한다. 중요)
	
	int[] nums = { 1, 2, 3, 4, 5 };
	int index = 1;
	int value = 9; // 삽입할 값
	
	
	System.out.println("nums[0] = " + nums[0]);
	System.out.println("nums[3] = " + nums[3]);
	
	//초기상태
	System.out.println(Arrays.toString(nums));
	
	// 한칸씩 복사
	for (int i=nums.length-2; i>=index; i--) { 
		System.out.println(i);
		nums[i+1] = nums[i];
		System.out.println(Arrays.toString(nums));
		
		
	}
	// 삽입
	nums[index] = value;
	System.out.println(Arrays.toString(nums));
	
	System.out.println("nums[0] = " + nums[0]);
	System.out.println("nums[3] = " + nums[3]);
	
	
	
	
}

private static void m12() {
	
	
	int[] nums = { 5, 3, 1, 4, 2 };
	
	
	String[] names = { "홍길동", "아무개", "테스트", "유재석", "강아지", "고양이", "도깨비", "박명수", "조세호", "병아리" };
	
	// sort(Object) 문자
	
	// Quick Sort
	Arrays.sort(nums);
	System.out.println(Arrays.toString(nums));
	
	Arrays.sort(names);
	System.out.println(Arrays.toString(names));
	
	
}

private static void m11() {
	
	// 배열 초기화 리스트
	
	int[] nums1 = new int[5];
	
	//값이 불규칙
	nums1[0] = 95;
	nums1[1] = 88;
	nums1[2] = 67;
	nums1[3] = 89;
	nums1[4] = 64;
	
	System.out.println(Arrays.toString(nums1));
	

	int[] nums2 = new int[] {95, 88, 67, 89, 64}; // 영역의 블럭이 아니므로 반드시 뒤에 세미콜론이 있어야 한다
	System.out.println(Arrays.toString(nums2));
	
	// 초기화 리스트 
	int[] nums3 = {95, 88, 67, 89, 64};
	System.out.println(Arrays.toString(nums3));
	
	
	String[] names1 = new String[3];
	
	names1[0] = "홍길동";
	names1[1] = "임꺽정";
	names1[2] = "도깨비";

	String[] names2 = {"홍길동", "임꺽정", "도깨비"};
	
	System.out.println(Arrays.toString(names1));
	System.out.println(Arrays.toString(names2));
	

}

private static void m10() {
	
	// 배열 자동 초기화
	// - 배열은 생성 직후 모든 요소(방)가 초기화가 된다. 
	
	// 초기화 규칙
	// 1. 정수배열 > 0
	// 2. 실수배열 > 0.0
	// 3. 문자열 > \0 (\u0000)
	// 4. 논리배열 > false
	// 5. 참조형배열 > null
	
	int[] list1 = new int[3];
	System.out.println(Arrays.toString(list1));
	
	byte[] list2 = new byte[3];
	System.out.println(Arrays.toString(list2));
	
	double[] list3 = new double[3];
	System.out.println(Arrays.toString(list3));
	
	char[] list4 = new char[3];
	System.out.println(Arrays.toString(list4));
	
	boolean[] list5 = new boolean[3];
	System.out.println(Arrays.toString(list5));
	
	
	String[] list6 = new String[3];
	System.out.println(Arrays.toString(list6));
	
			
	
}

private static void m9() {
	
	
	// Arrays 클래스
	// - 유틸리티 클래스
	// - 배열과 관련된 여러가지 기능을 구현한 클래스
	// - 배열을 조작하는 편리한 기능을 제공하는 역할
	
	int[] nums = new int[3];
	
	nums[0] = 10;
	nums[1] = 20;
	nums[2] = 30;
	
	// 배열의 상태를 확인?
	// [I@2ff4acd0
	// [I > int[]
	// @ 
	// 2ff4acd0 > 메모리 주소  
	System.out.println(nums); // 쓸모없음 
	
	// 직접 출력
	printArray(nums); //메서드로 만듦
	
	//  하지만 만들지 않아도 자바가 제공 
	
	System.out.println(Arrays.toString(nums)); // dump (덤프) 메서드 , 배열을 문자열로 만들어주겠다는.. 
	
	
	// *** C계열의 언어들은 범위를 나타낼때
	// - 시작위치(inclusive) ~ 끝위치(exclusive)
	
	
	
	// 깊은 복사

	
	int [] copy; // 복사본 배열 변수 먼저 만들기
	
	copy = Arrays.copyOfRange(nums, 0, nums.length); // 몇번째 방 부터 몇번째 방까지 복사할래?  length만 적는 이유, 끝위치 포함 안시켜서 
	
	nums[0] = 100;
	System.out.println(Arrays.toString(nums));
	System.out.println(Arrays.toString(copy));
	
	
	
	
	
}

public static void printArray(int[] nums) {
	for (int i=0; i<nums.length; i++) {
		System.out.printf
		("%3d", nums[i]);
	} System.out.println();
}

private static void m8() {
	
	// 배열 복사
	// 1. 얕은 복사, Shallow Copy
	// - 주소값 복사
	// - Side Effect 발생
	
	// 2. 깊은 복사, Deep Copy
	// - 실제 배열 복사
	// - Side Effect 발생 안함
	
	int[] nums = new int[3];
	
	nums[0] = 10;
	nums[1] = 20;
	nums[2] = 30;
	
	int[] copy = new int[3]; // 직접 방을 만든다..
	
	for (int i=0; i<nums.length; i++) {
		
		//방과 방끼리의 복사 > 요소끼리의 복사
		//int = int (값형끼리의 복사) 
		copy[i] = nums[i];
		
	}
	
	nums[0] = 100;
	System.out.println(copy[0]); // 안변함..
	
	
	
	
	
	
	
	
	
}

private static void m7() {
	
	
	int a = 10; //원본 
	
	changValue(a);
	
	System.out.println(a); // 지역변수이고 값형변수라  20이 아니다 
	
	
	int[] nums = new int [3];
	nums[0] = 10;
	nums[1] = 20;
	nums[2] = 30;
	
	changeArray(nums);
	
	System.out.println(nums[0]); // 참조형이므로 지역변수의 생명주기랑 상관없이 바뀌어 있음
	
}

private static void changeArray(int[] nums) { // 실인자 가인자 복사, 
	
	nums[0] =123;
	System.out.println(nums[0]);
	//참조형을 사용하면, 굳이 return 값을 사용하지 않아도 돌려준다
}

private static void changValue(int a) {
	
	a = 20; //수정
	System.out.println(a);
}

private static void m6() {
	
	// *** 반드시 이해해야 함
	// 배열 복사(= 참조형 복사)
	
	//값형 복사
	int a = 10;
	int b;
	
	b = a;
	
	// 값형 > 원본을 수정해도 복사본에 영향을 주지 않는다. > Side effect 발생하지 않는다. 
	a = 20; // 원본 수정
	System.out.println("a: " + a);
	System.out.println("b: " + b); // 안바뀜 , 복사를 한것이지 같은 아이가 아니므로...
	System.out.println();
	
	
	int[] nums = new int[3];
	
	nums[0] = 10;
	nums[1] = 20;
	nums[2] = 30;
	
	int[] copy;
	
	// int[] 가 자료형임 읽을때 int 배열이라고 읽음
	// int[] = int[]
	copy = nums; // 참조가 늘어난 것... 모든 참조형은 실제 데이터 복사가 아닌 주소값을 복사한다. 
	
	System.out.println(copy[0]);
	System.out.println(copy[1]);
	System.out.println(copy[2]);
	
	// 원본을 수정하면 복사본도 수정된다.
	// 복사본을 수정하면 원본도 수정된다.
	// >  Side effect가 발생한다. 
	
	nums[0] = 100; //수정
	
	System.out.println(copy[0]); // 바뀜..! 
	System.out.println(copy[1]);
	System.out.println(copy[2]);
	
	copy[1] = 200; //반대로 수정
	System.out.println(nums[1]);
	
	// 문자열 빼고 모든 참조형의 특징이다. 
	// 문자열은 소속은 참조형인데, 특성은 값형을 많이 가지고 있음 
	
	
	
	
	
	
}

private static void m5() {
	
	// 값형 vs 참조형
	// - 값형 > 변수에 데이터를 직접 저장
	// - 참조형 > 데이터는 따로 생성 + 변수에 메모리 주소값 저장 
	
	// *** 원인
	// - 데이터 크기가 일정 > 값형
	// - 데이터 크기가 일정하지 않음 > 참조형
	// - *** 변수만 보고 데이터의 길이를 추측 가능 > 값형
	// - *** 변수만 보고 데이터의 길이를 추측 불가능 > 참조형
	
	int a1 = 10; 
	// a1 의 메모리(공간) 크기? 4byte
	
	int a2 = 2000000000;
	// a2 의 메모리 크기? 4byte
	
	String s1 = "홍길동";
	// s1의 메모리 크기?  6byte (heap 위치, 2 * 3byte) / 참조형의 크기? stack 위치 
	// Stack 은 우리가 직접적으로 접근할 수 있으나, Heap 은 불가 
	
	String s2 = "안녕하세요";
	// s2의 메모리 크기? 10byte 
	
	
	int[] nums1 = new int[3];
	// 12byte
	
	int[] nums2 = new int[5]
	// 20byte
			
	
}

private static void m4() {
	
	// 각 자료형 > 배열
	// 정수 배열(byte, short, int, long)
	byte[] list1 = new byte[5];
	list1[0] = 10;
	System.out.println(list1[0]);
	
	// 실수 배열(float, double)
	double[] list2 = new double[5];
	list2[0] = 3.14;
	System.out.println(list2[0]);
	
	// 문자 배열(char) == String (문자열) 
	char[] list3 = new char[5];
	list3[0] = 'A';
	System.out.println(list3[0]);
	
	// 논리 배열(boolean)
	boolean[] list4 = new boolean[5];
	list4[0] = true;
	System.out.println(list4[0]);
	
	
	// 참조형 배열
	String[] list5 = new String[5];
	list5[0] = "홍길동";
	System.out.println(list5[0]);
	
	Calendar c1 = Calendar.getInstance(); 
	// 변수를 만들 수 있는 모든 자료형은 배열도 만들 수 있다

	Calendar[] list6 = new Calendar[5];
	list6[0] = Calendar.getInstance(); 		//Calendar.getInstance();  도 해야 현재 시간이 들어간다. 안넣으면 null 값이없음 
	System.out.println(list6[0]);
	
	
	
	
	
	
}

private static void m3() {
	
	
	//참조형의 특징
	// - 모든 참조형들은 공간을 초기화하지 않아도 자동으로 초기화가 된다. (값형은 X) 
	// 예) 		System.out.println(num); 에러남
	
	int[] nums = new int[10];
	
	nums[0] = 10;
	nums[1] = 20;
	nums[2] = 30;
	
	System.out.println(nums[0]);
	System.out.println(nums[1]);
	System.out.println(nums[2]);
	System.out.println(nums[3]); // 0이 들어 있는 이유,  참조형의 특징 때문에.. 
	
	
	// 배열의 길이 = 10
	// 첨자의 범위 = 0 ~ 9
	// 첨자의 범위 = 0 ~ 길이-1
	
	// ArrayIndexOutOfBoundsException
	// Index 10 out of bounds for length 10
	// System.out.println(nums[10]); // 최대방의 길이가 9, 존재하지 않는 방번호 - 에러

	
	// 배열 탐색 > for문 사용
	for (int i=0; i<nums.length; i++) {
		System.out.printf("nums[%d] = %d\n", i, nums[i]);
		
	} // 전형적인 배열을 탐색할때 쓰는 for 
	
	// 배열은 모든 자료형으로 만들 수 있다.
	
	
}

private static void m2() {
	
	// 요구사항] 학생 3명 > 국어 점수 > 총점, 평균
	// 추가사항] 학생 수 증가 > 300명
	
	// 배열은 참조형이다
	// 배열 선언하기
	// - 자료형 [] 변수명 = new 자료형 [길이];
	// - 배열타입 배열명 = new 배열타입 [배열의길이];
	int [] kors = new int[3]; // 왼쪽 : kors 은 Stack에, Heap 주소값 저장, 오른쪽 : heap 에 만들어지며, 연속으로 3칸, 4byte 씩 12byte 
	// 배열은 변수를 한꺼번에 만드는 일
	// 배열의 index (첨자) : 각각 방의 번호
	// 배열의 요소 element : 각각의 방 
	
	// 배열의 방(요소, Element)에 접근 > 방 번호(첨자, Index) 사용
	// 배열의 길이 = 방의 갯수
	// 같은 성질의 같은 자료형일 때 배열을 만든다. 

	kors [0] = 100; // 방 3개 중 1번째 방 
	kors [1] = 90;
	kors [2] = 80;

	
	// int total = kors[0] + kors[1] + kors[2];
	int total = 0;
	
	for (int i=0; i<kors.length; i++) {// 루프변수를 통해 모든 배열의 방번호를 얻을 수 있게 됨
		total += kors[i];
	}
	
	double avg = (double)total / kors.length; // 속성, 필드, 프로퍼티
	
	System.out.printf("총점: %d점, 평균 %.1f점\n", total, avg);
	
	
	
	
}

private static void m1() {
	
	// 요구사항] 학생 3명 > 국어 점수 > 총점, 평균 
	// 추가사항] 학생수 증가 > 300명 
	
	
	int kor1;
	int kor2;
	int kor3;
	
	// + 297 추가 선언
	
	kor1 = 100;
	kor2 = 90;
	kor3 = 80;
	
	// + 297 초기화
	
	int total = kor1 + kor2 + kor3; // + kor4 + kor5 + ... + kor300
	
	double avg = total / 3.0; // 3.0 > 300.0
	
	System.out.printf("총점: %d점, 평균 %.1f점\n", total, avg);
	
	
}

}

profile
공부기록

0개의 댓글