과학

자바로 프로그래밍에 입문할래요: 1.4. 배열 (3)

1.4. 배열 (2)

1.4 배열 (1)

1.3. 조건문과 반복문 (2)

1.3. 조건문과 반복문 (1)

1.2. 내장 자료형 (2)

1.2. 내장 자료형 (1)

0.0. 여는 글, 1.1. 첫 프로그램 만들기

 

========================

 

 2차원 배열(Two-dimensional arrays)

  많은 응용프로그램에서 정보를 저장하기 위해 사용하는 편리한 방법 중 하나는 사각형의 표에서 행과 열을 이용해 참조하는 것입니다.

  i행 j열의 2차원 배열 요소에 접근하기 위해서 우리는 a[i][j] 라는 표기법을 사용합니다. 2차원의 배열을 선언하기 위해서는, 대괄호쌍 하나를 더 사용해야 합니다. 생성하기 위해서는, 각 괄호 안에 행의 수와 열의 수를 명시합니다.

 

 
double[][] a = new double[M][N];

 

  우리는 이를 M*N(M-by-N) 배열이라고 합니다. 1차원 배열과 같이 모든 숫자는 0으로, boolean 값은 false로 초기화됩니다.

 

 

초기화

  2차원 배열을 초기화하기 위해서는, 이중 반복문을 이용합니다. 다음은 2차원 배열을 초기화하는 코드 조각입니다.

 

 
doubled [] a;
a = new double[M][N];
for (int i = 0; i < M; i++)
{ // Initialize the ith row.
	for (int j = 0; j < N; j++)
		a[i][j] = 0.0;
}

 

  곧 보겠지만, 이 코드는 2차원 배열의 요소를 접근하고 수정하기 위해 흔히 사용되는 방법입니다. 

 

 

출력

  우리는 2차원 배열을 출력하기 위해 다음 코드 조각을 활용할 수 있습니다.

 

 
doubled [] a;
a = new double[M][N];
for (int i = 0; i < M; i++)
{ // Initialize the ith row.
	for (int j = 0; j < N; j++)
		System.out.print(a[i][j] + " ");
	System.out.println();
}

 

 

메모리 표현

  자바는 2차원 배열을, 배열의 배열로 표현합니다. M*N 배열은, 크기가 N인 배열을 원소로 가지는, 크기가 M인 배열입니다. 자바의 2차원 배열 a[][]에서, 우리는 a[i]를 통해 i번째 행을 참조할 수 있습니다.(마치 1차원 배열처럼 말이죠) 하지만 2차원이니, 열을 참조할 방법이 결국 필요하겠죠.

 

 

 

컴파일 시기에 값을 설정하기

  2차원 배열을 초기화 하기 위해서는, 각 중괄호 안에서 한 행씩을 초기화 하고, 그것들을 쉼표로 구분합니다. 다음 코드 조각을 참고하세요.

 

 
int[][] a =
	{
		{ 99, 85, 98, 0 },
		{ 98, 57, 78, 0 },
		{ 92, 77, 76, 0 },
		{ 94, 32, 11. 0 },
		{ 99, 34, 22, 0 },
		{ 90, 46, 54, 0 },
		{ 76, 59, 88, 0 },
		{ 92, 66, 89, 0 },
		{ 97, 71, 24, 0 },
		{ 89, 29, 38, 0 },
		{  0,  0,  0, 0 }
	};

 

 

스프레드시트(Spreadsheets)

  배열의 흔한 사용법 중 하나는 표의 숫자들을 활용하는 스프레드시트입니다. 예를 들어, 교사가 M명의 학생과 N개의 과목 점수, 각 마지막 줄은 평균 점수를 담는 (M+1)*(N+1) 배열을 이용 할 수 있습니다. 다음 그림을 참고하세요.

 

 

 

 

행렬 연산

  과학과 공학 분야에서는 행렬 연산을 위해 흔히 2차원 배열을 사용합니다. 두 N*N 행렬을 다음과 같이 더해볼 수 있겠죠.

 

 

 

 
double[][] c = new double[N][N];
for (int i = 0; i < N; i++)
	for (int j = 0; j < N; j++)
		c[i][j] = a[i][j] + b[i][j];

 

  비슷하게, 행렬곱도 해볼 수 있을 것입니다. 삼중 반복문이 조금은 익숙지 않으실 수도 있겠지만, 천천히 눈으로 따라가보세요.

 


 
double[][] c = new double[N][N];
for (int i = 0; i < N; i++)
{
	for (int j = 0; j < N; j++)
	{
		// Compute dot product of row i and column j,
		for (int k = 0; k < N; k++)
			c[i][j] += a[i][k] * b[k][j];
	}
}

 

 

그 외의 행렬 곱들

  이는 간단히 그림만 첨부합니다. 흥미가 생긴다면 직접 코딩해서 따라해보세요.

 

 

 

 

 

 

가변 배열(Ragged arrays)

  모두 같은 크기의 열을 굳이 사용할 필요가 없는 경우도 있습니다. 열의 개수가 일정하지 않은 배열을 가변 배열이라고 합니다. 가변 배열이 가능하다면, 배열을 처리하는 코드들에 좀 더 신경을 써야 합니다. 다음은 가변 배열의 요소들을 출력하는 코드입니다.

 

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

 

  이전에 봤던 코드와 뭐가 다를까요? 이 코드는 여러분이 자바 배열을 얼마나 이해했는지 시험합니다. 우리는 일반적으로 정사각 혹은 직사각형의 2차원 배열을 사용했습니다. 코드의 두 번째 for문에서 a[i].length를 사용한다는 것은, 곧 이 배열이 가변이라는 사실을 암시하는 것입니다.

 

 

다차원 배열(Multidimensional arrays)

  같은 표기법으로 몇 차원이든 계속해서 확장할 수 있습니다. 예를 들어 3차원 배열은 다음과 같이 사용할 수 있습니다.

 

 
double[][][] a = new double[N][N][N];

 

  또한 마찬가지로 a[i][j][k]와 같은 방식으로 참조하면 됩니다.

 

  2차원 배열은 행렬에 대한 자연스러운 표현을 가능하게 해주며, 이는 과학, 수학, 공학 등 다양한 분야에서 활용할 수 있게 해줍니다. 또한 아주 많은 양의 데이터를 쉽게 처리할 수 있게 해주며, 스프레드시트같이 활용할 수도 있습니다. 데카르트 좌표계를 통해, 2차, 3차원의 배열은 물리적 세계를 기반으로 한 모델들도 제공합니다. 

 

 

예제: self-avoiding random walks(자기 회피 무작위 보행)

  촘촘한 격자 형태로 설계된 거대한 도시의 길거리를 여러분의 애완견과 함께 걷는다고 생각해봅시다. 수직으로 N개의 거리, 수평으로 N개의 거리, 총 N*N개의 교차로가 있는 도시를 걷는 것이죠. 

 

 

 

 

  여러분은 도시의 정중앙에서 애완견과 함께 이 도시를 탈출하고 싶습니다. 다만, 교차로에서 어떤 방향으로 나아갈지는 무작위로 선택합니다. 애완견은 냄새에 예민하여 이미 방문한 적 있는 교차로는 방문하지 않으려고 합니다. 그렇다면 어느 순간에는 네 방향 전부 이미 방문한 교차로여서, 어느 곳도 갈 수 없는 상황에 맞닥뜨릴 수도 있습니다. 이를 dead-end라고 하죠. 아니면 다행히도 dead-end를 맞닥뜨리지 않고 도시 바깥으로 탈출할 수 있을지도 모릅니다.

 

  우리가 N*N 크기의 도시를 탈출할 가능성은 얼마나 있을까요? 이는 self-avoiding random walk라는 유명한 모델이며, 고분자학과 통계학 등 다양한 분야에서 대표적으로 응용되는 문제 중 하나입니다. 

 

 

프로그램 1.4.4: Self-avoiding random walks

 
public class SelfAvoidingWalk
{
	public static void main(String[] args)
	{ 	// Do T random self-avoiding walks
		// in an N-byN lattice
		int N = Integer.parseInt(args[0]);
		int T = Integer.parseInt(args[1]);;
		int deadEnds = 0;
		for (int t = 0; t < T; t++)
		{
			boolean[][] a = new boolean[N][N];
			int x = N / 2, y = N / 2;
			while (x > 0 && x < N - 1 && y > 0 && y < N - 1)
			{ // Check for dead end and make a random move.
				a[x][y] = true;
				if (a[x - 1][y] && a[x + 1][y] && a[x][y - 1] && a[x][y + 1])
				{
					deadEnds++;
					break;
				}
				double r = Math.random();
				if (r < 0.25)
				{
					if (!a[x + 1][y])
						x++;
				} else if (r < 0.50)
				{
					if (!a[x - 1][y])
						x--;
				} else if (r < 0.75)
				{
					if (!a[x][y + 1])
						y++;
				} else if (r < 1.00)
				{
					if (!a[x][y - 1])
						y--;
				}
			}
		}
		System.out.println(100 * deadEnds / T + "% dead ends");
	}
}
% java SelfAvoidingWalk 5 100
0% dead ends
% java SelfAvoidingWalk 40 100
80% dead ends
% java SelfAvoidingWalk 160 100
100% dead ends

 

  <프로그램 1.4.4>는 N과 T를 명령행 인자로 받아, N*N 도시 크기에서 T번 탈출을 시도합니다. 이후에 얼마나 dead-end에 도달하는지 비율을 출력합니다.

 

  이 프로그램을 이해하는 것은 어려운 도전이 될지도 모릅니다. 2차원 배열 a[][]는 해당 교차로의 방문 여부를 저장하는 배열입니다. true이면 방문한 것이고, false이면 방문하지 않은 것입니다. 또한 x와 y는 현재 위치한 교차로의 좌표입니다. 무작위로 생성된 r의 값에 따라, 각각 if문을 통해서 해당 방향의 교차로에 방문하지 않았다면 좌표를 해당 방향으로 수정해 방문합니다. dead-end에 도달하거나, 도시의 범위를 벗어날 때까지 이를 반복합니다.

 

 

 

 

  배열은 자바를 포함한 모든 프로그래밍 언어에서 찾을 수 있는 기초 요소입니다. 여지껏 배운 것들을 활용하면, 어떤 문제든지 프로그램을 통해 해결해낼 수 있을 것입니다. 이는 허투루 하는 소리가 아닙니다. 대부분의 알고리즘 테스팅은, 기본 자료형과 조건문, 반복문, 배열만으로도 충분히 해결할 수 있습니다. 여러분이 어떤 현실의 문제이든, 적절한 추상화를 통해 프로그램으로써 해결해낼 수 있는 역량을 갖추게 된 것입니다.

 

끝.

1개의 댓글

2021.05.03

잘보고 있어요

 

0
무분별한 사용은 차단될 수 있습니다.
번호 제목 글쓴이 추천 수 날짜
501 [과학] 자바로 프로그래밍에 입문할래요: 2.2. 라이브러리와 클라이... 4 스비니 6 2 일 전
500 [과학] 아무도 알고싶지 않을수도 있는 이야기 - NASA의 인증을 받은... 25 Te2t1c1e 14 5 일 전
499 [과학] 자바로 프로그래밍에 입문할래요: 2.1. 정적 메소드 (2) 8 스비니 0 10 일 전
498 [과학] 암흑에너지는 존재하는가? 19 월급받으며개드립하기 8 18 일 전
497 [과학] 자아도취에 빠져버린 오늘날의 과학계 9 위너스리그 11 18 일 전
496 [과학] 자바로 프로그래밍에 입문할래요: 2.1. 정적 메소드 (1) 4 스비니 2 19 일 전
495 [과학] 비트코인/블록체인 개념 안되는사람들을 위한 읽을거리 13 냥봉이 1 19 일 전
494 [과학] 자바로 프로그래밍에 입문할래요: 1.5. 입출력 (2) 16 스비니 2 29 일 전
493 [과학] 자바로 프로그래밍에 입문할래요: 1.5. 입출력 (1) 1 스비니 2 2021.05.09
492 [과학] 자바로 프로그래밍에 입문할래요: 1.4. 배열 (3) 1 스비니 4 2021.05.01
491 [과학] 일론 머스크는 스티브 잡스 같은 사람이다. (feat. 뉴럴링크) 38 빨머 20 2021.04.29
490 [과학] 자바로 프로그래밍에 입문할래요: 1.4. 배열 (2) 9 스비니 2 2021.04.23
489 [과학] 방사선에 관하여_20210423_Ch.4까지 완료 63 ptrtype01 4 2021.04.22
488 [과학] 日 자민당 의원이 공개한 원전오염수 성분 31 SOLEUS 16 2021.04.20
487 [과학] ??? : 한국이 오염수 더 많이 방류한다 빼애액 24 SOLEUS 13 2021.04.20
486 [과학] 일본의 방사능 기준치가 신용받지 못하는 이유 71 뭘까요 1 2021.04.19
485 [과학] 도쿄의 암 발생률. 27 뭘까요 5 2021.04.19
484 [과학] 일본은 과연 후쿠시마 인근만 방사능에 오염돼었을까? 13 뭘까요 10 2021.04.19
483 [과학] 일본이 주장하는 후쿠시마의 방사능량은 서울과 같다는게 사... 31 뭘까요 14 2021.04.19
482 [과학] 일본 후쿠시마 오염수 방류 팩트정리 21 뭘까요 7 2021.04.19