[알고리즘] 알고리즘 - # 2. 배열과 자바 접근

02-1 배열


자료구조(data structure) 🔧

데이터 단위와 데이터 자체 사이의 물리적 or 논리적인 관계

데이터 단위 : 데이터를 구성하는 한 덩어리
자료구조 : 자료를 효율적으로 이용할 수 있도록 컴퓨터에 저장하는 방법

배열(Array)

같은 자료형의 변수로 이루어진 구성 요소 (component)

✋(Java일 경우) new 연산자 생성 시, 배열 본체에 대한 참조 (stack/heap) 형태

 

초깃값(default value)

배열 뿐만이 아닌 클래스의 필드(인스턴스 변수, 클래스 변수)도 초깃값으로 초기화

종류 데이터 타입 출력되는 초기값
정수형 타입 byte 0
short
int
long 0.0l or 0.0L
char \u0000
실수형 타입 float 0.0f or 0.0F
double 0.0d or 0.0D
논리형 타입 boolean false
클래스(+String ), 배열 , 인터페이스  null
✍️ String 클래스
java.lang 패키지에 소속된 String 클래스

 

 

배열 초기화(array initializer)

 

배열의 요솟값을 초기화하며 배열 선언하기

 

배열 초기화(array initializer)를 사용하면 배열 본체의 생성과 동시에 각 요소의 초기화가 가능

package alogrithm_2_1;

public class IntArrayInit {
	
	public static void main(String[] args) {
		int[] a =  {1, 2, 3, 4, 5};
		
		
		for(int i=0; i < a.length; i++) {
			System.out.println("a[" + i + "] : " + a[i]);
		}
		
		
	}

}

 

배열의 복제(clone)

배열의 복제는 clone 메서드를 호출

 

💡 배열이름.clone() //배열 복제

 

package alogrithm_2_1;

public class CloneArray {
	
	public static void main(String[] args) {
		int[] a =  {1, 2, 3, 4, 5};
		int[] b = a.clone();
		
		b[3] = 0;
		
		
		System.out.print("a = ");
		for(int i=0; i < a.length; i++) {
			System.out.print(" " + a[i]);
		}
		
		System.out.println();
		System.out.print("b = ");
		for(int i=0; i < b.length; i++) {
			System.out.print(" " + b[i]);
		}
		
		
	}

}

✋배열 변수 b의 참조가 배열 a의 본체 그 자체가 아닌 그 복제라는 것을 확인!

 

  • 배열 요소의 최댓값 구하기
package alogrithm_2_1;

import java.util.Scanner;

public class MaxOfArray {
	
	static int maxOf(int[] a) {
		
		int max = a[0];
		
		
		for(int j = 0; j < a.length; j++) {
			if(max < a[j]) { //a[i] > max
				max = a[j];
			}
		}		
		return max;
		
	}
	
	
	public static void main(String[] args) {
		Scanner intNum = new Scanner(System.in);
		Scanner arrNum = new Scanner(System.in);//Scanner 클래스는 한 번 선언하면 계속 우려먹을 수 있음
		
		System.out.println("키의 최댓값을 구합니다.");
		System.out.println("사람 수 :");
		int personNum = intNum.nextInt();
		
		int[] personArr = new int[personNum];
		
		for(int i = 0; i < personArr.length; i++) {
			System.out.print("height["+ i + "] : ");
			int heightNum = arrNum.nextInt();
			personArr[i] = heightNum;// 34, 35줄 합쳐서 personArr[i] = arrNum.nextInt();
			System.out.println();
		}
		
		System.out.println("최댓값은 " + maxOf(personArr) + "입니다.");
		
	}

}

 


 

✍️접근 제한자란?

객체의 멤버에 대한 접근을 제한

 

  • 제한자의 종류
public  모든 접근 허용
protected 
같은 패키지(폴더)의 객체, 상속 관계의 객체 허용
default  같은 패키지(폴더)의 객체 허용
private  현재의 객체 안에서만 허용
  • 접근 제한자 허용
클래스 (Class) public, default
생성자 (Constructor) public, protected, default, private
멤버변수 (Member Variable) public, protected, default, private
멤버메서드 (Member Method) public, protected, default, private
지역 변수 (local Variable) 접근 제한자 사용 못함

 

  • 난수 사용해 배열의 요솟값 설정
package alogrithm_2_1;

import java.util.Random;
import java.util.Scanner;

public class MaxOfArrayRand {
	
	static int maxOf(int[] a) {
		
		int max = a[0];
		
		
		for(int j = 0; j < a.length; j++) {
			if(max < a[j]) { //a[i] > max
				max = a[j];
			}
		}		
		return max;
		
	}
	
	
	public static void main(String[] args) {
		Scanner intNum = new Scanner(System.in);
		Random randNum = new Random();
		
		System.out.println("키의 최댓값을 구합니다.");
		System.out.println("사람 수 :");
		int personNum = intNum.nextInt();
		
		int[] personArr = new int[personNum];
		
		for(int i = 0; i < personArr.length; i++) {
			personArr[i] = randNum.nextInt(90);
			System.out.print("height["+ i + "] : " +  personArr[i]);
			System.out.println();
		}
		
		System.out.println("최댓값은 " + maxOf(personArr) + "입니다.");
		
	}

}
✅ Random class method 의 .nextInt(int i) 메서드는 0부터 i까지의 랜덤한 숫자를 return

 

 난수의 생성
난수는 'seed' 라는 수의 값을 바탕으로 여러 연산을 수행하여 얻음 (난수표 존재)

→ 컴퓨터에서 생성하는 난수는 진짜 난수가 아니다 ❌, 미리 컴퓨터가 계산해 둔 의사 난수
→ 컴퓨터 처음 킬 때 난수표 생성하여 보관

진짜 난수 :
 로또

의사 난수 : 실제와 비슷한 값


⭐ 매번 같은 값으로 난수를 가져오면 처음 실행할 때 외에는 난수라고 할 수 없음
⭐ seed 값을 항상 다르게 주기 위해 현재 시간을 이용하는 것이 일반적


  • 배열 요소를 역순으로 정렬
-package alogrithm_2_1;

import java.util.Random;
import java.util.Scanner;

public class ReverseArray {
	
	static void swap(int[] a, int idx1, int idx2) {
		int t = a[idx1];
		a[idx1] = a[idx2];
		a[idx2] = t;
	}
	
	
	static void reverse(int[] id) {

		for(int i = 0; i < id.length/2; i++) {
			swap(id, i, id.length-i-1 );
		}
		
	}
	
	
	public static void main(String[] args) {
		Scanner intNum = new Scanner(System.in);

		System.out.print("요솟수 : ");
		int num = intNum.nextInt();
		
		int[] numArr = new int[num];
		
		for (int i = 0; i < numArr.length; i++) {
			System.out.print("x["+ i + "] : " );
			numArr[i] = intNum.nextInt();
			System.out.println();
		}
		
		System.out.println("요소를 역순으로 정렬했습니다.");
		
		reverse(numArr);
		
		for (int i = 0; i < numArr.length; i++) {
			System.out.print("x["+ i + "] : " + numArr[i] );
		}
	}

}

 


✍️ 형 import 선언

간단한 클래스 이름만으로 클래스를 사용하도록 하는 것이 형 import 선언

 

메서드 호출
java.utill.Scanner sacn = new java.utill.Sacnner();

import 선언
import java.utill.Scanner;

 


 

 

  • 두 배열의 비교
package alogrithm_2_1;

import java.util.Scanner;

public class ArrayEqual {
	
	static void equals(int[] a, int[] b) {
		boolean check = true; 
		
		if(a.length == b.length) {
			for (int k = 0; k < a.length; k++) { 
				if(a[k] != b[k]) {
					check = false;
				}
			}
		} else {
			check = false;
		}
	
		if(check) {
			System.out.println("배열 a와 b는 같습니다.");
		}else {
			System.out.println("배열 a와 b는 다릅니다.");
		}
			
		
	}
	
	public static void main(String[] args) {
		Scanner num = new Scanner(System.in);
		
		System.out.print("배열 a의 요솟수 : ");
		int aNum = num.nextInt();
		
		int[] aArr = new int[aNum];
		
		for(int i = 0; i < aNum; i++) {
			System.out.print("a[" + i + "] : ");
			aArr[i] = num.nextInt();
			System.out.println();
		}
		
		System.out.print("배열 b의 요솟수 : ");
		int bNum = num.nextInt();
		
		int[] bArr = new int[bNum];
		
		for(int i = 0; i < bNum; i++) {
			System.out.print("b[" + i + "] : ");
			bArr[i] = num.nextInt();
			System.out.println();
		}
		
		equals(aArr, bArr);
	}

}

 

  • 기수변환

정숫값을 임의의 기수로 변환하는 알고리즘

✍️ 기수에 대해
n진수는 n을 기수로 하는 수
기수 : 수를 나타내는 데 기초가 되는 수
package alogrithm_2_1;

import java.util.Scanner;

public class CardConvRev {

	static int cardConvR(int no, int cd, char[] cno) {
		int digits = 0; // 변환 뒤의 자릿수
		String dChar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		
		do {
			cno[digits++] = dChar.charAt(no % cd);
			System.out.println("변환 뒤의 자릿수  : " + digits);
			System.out.println("변환하는 기수에서 십진수 나눈 나머지  : " + cno[digits]);
			no /= cd;
			System.out.println("입력받은 십진수를 변환하는 기수에 나눈 몫 : "+ no);
		} while (no != 0);
		
		return digits;
	}
	
	public static void main(String[] args) {
		Scanner num = new Scanner(System.in);
		int no; //입력받은 십진수
		int cd; //변환하는 기수
		int dno; //십진수 -> 변환된 기수의 자릿수
		int retry;
		char[] cno = new char[32]; //변환 뒤의 각 자리를 저장하는 문자 배열
		
		System.out.println("10진수를 기수 변환합니다.");
		
		do {
			do { M
				System.out.print("변환하는 음이 아닌 정수 : ");
				no = num.nextInt();
			} while (no < 0);
			
			do {
				System.out.println("어떤 진수로 변환(2~36) : ");
				cd = num.nextInt();
			} while (cd < 2 || cd > 36);
			
			dno = cardConvR(no, cd, cno);
			
			System.out.println(cd + "진수로는 ");
			for(int i = dno-1; i >= 0; i--) {
				System.out.print(cno[i] + " ");
			}
			System.out.println("입니다.");
			
			System.out.println("restart? (1.Yes/ 2.No)");
			retry = num.nextInt();
		} while(retry == 1);
	}
}

다차원 배열

보통의 배열(1차원 배열)과 구별하기 위해 사용

 

2차원 배열 : 배열을 구성 요소로 하는 것

3차원 배열 : 2차원 배열을 구성 요소 하는 것

 

✋ 자바에서는 다차원 배열이라는 건 존재하지 않음.

2차원 배열을 '배열의 배열'

3차원 배열을 '배열의 배열의 배열'

 

 int[][] x = new int[2][4]; //"int 형을 구성 자료형으로 하는 배열"을 구성 자료형으로 하는 배열

 


✍️배열

  • 빈 배열(empty array)

배열 요솟수가 0인 배열

 

  • 배열 요소의 접근

배열의 접근은 모두 런타임(실행 시)에 검사

0미만 또는 배열 요솟수 이상의 인덱스를 사용하면 IndexOutOfBoundsException 발생

 

  • 배열 초기화의 쉼표
int[] a = {1, 2, 3, 4,}

static int[][] may = {
		{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
		{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, //추가 쉼표(,)
}

* 추가 쉼표(,) :  한 행의 초기화를 삽입할 때 쉼표를 빠뜨리는 것을 방지하는 효과

 

 


 

해당 내용은 Do it! 자료구조와 함께 배우는 알고리즘 입문[자바편] 을 참고하여 정리했습니다.