공부방

2차원 배열, 카운팅 정렬 본문

알고리즘/List

2차원 배열, 카운팅 정렬

코딩 화이팅 2023. 2. 16. 13:11

2차원 배열

package test01;

public class Test1_ArrayTest {
	public static void main(String[] args) {
		int[][] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

		int n = arr.length;
		int m = arr[0].length;

		// 1. 행 우선 순회
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				System.out.printf("%3d", arr[i][j]);
			}
			System.out.println();
		}
		System.out.println();
		// 2. 행 역우선 순회
		for (int i = 0; i < n; i++) {
			for (int j = m - 1; j >= 0; j--) {
				System.out.printf("%3d", arr[i][j]);
			}
			System.out.println();
		}
		System.out.println();
		// 3. 열 우선 순회
		for (int j = 0; j < m; j++) {
			for (int i = 0; i < n; i++) {
				System.out.printf("%3d", arr[i][j]);
			}
			System.out.println();
		}
		System.out.println();
		// 4. 열 역우선 순회
		for (int j = 0; j < m; j++) {
			for (int i = n - 1; i >= 0; i--) {
				System.out.printf("%3d", arr[i][j]);
			}
			System.out.println();
		}
		System.out.println();
		// 5-1. 지그재그 순회
		for (int i = 0; i < n; i++) {
			if (i % 2 == 0) {
				for (int j = 0; j < m; j++) {
					System.out.printf("%3d", arr[i][j]);
				}
				System.out.println();
			} else {
				for (int j = m - 1; j >= 0; j--) {
					System.out.printf("%3d", arr[i][j]);
				}
				System.out.println();
			}
		}
		System.out.println();
		// 5-2. 지그재그 순회
		for (int i = 0; i < n; i++) {
			if (i % 2 == 0) {
				for (int j = 0; j < m; j++) {
					System.out.printf("%3d", arr[i][j]);
				}
				System.out.println();
			} else {
				for (int j = 0; j < m; j++) {
					System.out.printf("%3d", arr[i][m - 1 - j]);
				}
				System.out.println();
			}
		}
		System.out.println();
		// 5-3. 지그재그 순회
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				System.out.printf("%3d", arr[i][j + (m - 1 - 2 * j) * (i % 2)]);
			}
			System.out.println();
		}
		System.out.println();

	}
}
//
  1  2  3
  4  5  6
  7  8  9

  3  2  1
  6  5  4
  9  8  7

  1  4  7
  2  5  8
  3  6  9

  7  4  1
  8  5  2
  9  6  3

  1  2  3
  6  5  4
  7  8  9

  1  2  3
  6  5  4
  7  8  9

  1  2  3
  6  5  4
  7  8  9

델타 배열

package test01;

public class Test2_Delta {
	public static void main(String[] args) {
		int[][] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

		int N = 3;
		int r =  1;
		int c = 1;

		int[] dr = { -1, 1, 0, 0 };
		int[] dc = { 0, 0, -1, 1 };
		//상하좌우
		//인덱스
		//0-상
		//1-하
		//2-좌
		//3-우
		int[][] drc = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
		
		for (int d = 0; d < 4; d++) {//0~3까지 반복을 하며 dr,dc 배열을 더하고 빼며
			//원래의 좌표값에서 새로운 옮겨진 좌표들을 찾아줌.
			int nr = r + dr[d];
			int nc = c + dc[d];
			
//			경계조건-밖으로 넘어가는 걸 방지
			if (nr >= 0 && nr < N && nc >= 0 && nc < N) {
				System.out.println(arr[nr][nc]);
			}
			
			//경계조건-밖으로 넘어가면 그냥 패스
//			if (nr < 0 || nr >= N || nc < 0 || nc >= N)
//				continue;
//			System.out.println(arr[nr][nc]);
		}
		
		//대각선
		int[] dr2= {-1,-1,1,1};
		int[] dc2= {-1,1,-1,1};
		
		for (int d = 0; d < 4; d++) {//0~3까지 반복을 하며 dr,dc 배열을 더하고 빼며
			//원래의 좌표값에서 새로운 옮겨진 좌표들을 찾아줌.
			int nr = r + dr2[d];
			int nc = c + dc2[d];
			
			//경계조건-밖으로 넘어가는 걸 방지
//			if (nr >= 0 && nr < N && nc >= 0 && nc < N) {
//				System.out.println(arr[nr][nc]);
//			}
			
			//경계조건-밖으로 넘어가면 그냥 패스
			if (nr < 0 || nr >= N || nc < 0 || nc >= N)
				continue;
			System.out.println(arr[nr][nc]);
		}
		
		//8방향
		//크기가 8인 델타 배열을 만들고
		//반복을 8번 돌기
		
	}
}
//
2
8
4
6
1
3
7
9

전치 행렬

package test01;
import java.util.Arrays;

public class Test3_TransposedMatrix {
	public static void main(String[] args) {
		// 전치행렬
		int[][] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
		int N = 3;
		for (int[] a : arr) {
			System.out.println(Arrays.toString(a));
		}

		// 전치행렬
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (i < j) {
					int tmp = arr[i][j];
					arr[i][j] = arr[j][i];
					arr[j][i] = tmp;
				}
			}
		}
		System.out.println("----------------------");
		for (int[] a : arr) {
			System.out.println(Arrays.toString(a));
		}

		//윗삼각형 영역
//		for (int i = 0; i < N; i++) {
//			for (int j = i + 1; j < N; j++) {
//				int tmp = arr[i][j];
//				arr[i][j] = arr[j][i];
//				arr[j][i] = tmp;
//			}
//		}
//		System.out.println("----------------------");
//		for (int[] a : arr) {
//			System.out.println(Arrays.toString(a));
//		}
	}
}
//
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
----------------------
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]

카운팅 정렬

항목들의 순서를 결정하기 위해 집합에 각 항목이 몇 개씩 있는지 세는 작업을 하여, 선형 시간에 정렬하는 효율적인 알고리즘

  • 정수나 정수로 표현할 수 있는 자료에 대해서만 적용 가능
  • 각 항목의 발생 회수를 기록하기 위해, 정수 항목으로 인덱스 되는 카운트들의 배열을 사용하기 때문이다.
  • 카운트들을 위한 충분한 공간을 할당하려면 집합 내의 가장 큰 정수를 알아야 한다.
  • 시간 복잡도: O(n+k)-n은 배열의 길이, k는 정수의 최대값
package test02;

import java.util.Arrays;

public class test5 {
	public static void main(String[] args) {
		int[] arr = { 5, 2, 4, 1, 2, 3, 3 };

		// 1단계
		// 주어진 배열 arr에서 최대값을 찾는다.
		// 그 수를 이용해서 카운팅 배열을 만든다.

		int max = -1;
		for (int i = 0; i < arr.length; i++) {
			if (max < arr[i]) {
				max = arr[i];
			}
		}
		System.out.println(max);// 최대값이 뭔지 확인해보자.

		// 2단계

		// 카운팅 배열
		// count[i]:i의 개수
		int[] count = new int[max + 1];// 최대값을 찾으면 그 최대값까지 카운팅해줄 수 있는 배열을 만든다.

		for (int i = 0; i < arr.length; i++) {
			count[arr[i]]++;
		}
		System.out.println(Arrays.toString(count));// 최대 값까지 몇 번 나왔는지 확인해준다.

		// 누적합 배열
		// =prefix sum
		// prefix[i]=count[0]+count[1]+count[2]+...+count[i];
		// suffix[i]=count[i]+count[i+1]+...+count[n-2]+count[n-1];

		// 굳이 배열을 하나 더 만들 필요 없긴 함
//		int[] prefix=new int[6];
//		prefix[0]=count[0];
//		for (int i = 1; i <= 5; i++) {
//			prefix[i]=prefix[i-1]+count[i];
//		}

		// 3단계
		// count배열을 prefix 배열로
//		for (int i = 1; i <= 5; i++) {
//			count[i] += count[i - 1];
//		}
		int[] countSum=new int[count.length];
		for (int i = 1; i < count.length; i++) {
			countSum[i]+=countSum[i-1]+count[i];
		}
		
		System.out.println(Arrays.toString(countSum));

		// 4단계
		// arr배열을 다시 돌면서
		// 새로운 배열의 새로운 좌표에 옮긴다.
		//{ 5, 2, 4, 1, 2, 3, 3 }
		int[] arr2 = new int[arr.length];
		for (int i = 0; i < arr.length; i++) {
			arr2[countSum[arr[i]] - 1] = arr[i];
			countSum[arr[i]]--;
		}
		System.out.println(Arrays.toString(countSum));//남은 누적카운팅배열 수
		System.out.println(Arrays.toString(arr2));//최종 정렬
	}
}
//
5
[0, 1, 2, 2, 1, 1]
[0, 1, 3, 5, 6, 7]
[0, 0, 1, 3, 5, 6]
[1, 2, 2, 3, 3, 4, 5]

'알고리즘 > List' 카테고리의 다른 글

String  (0) 2023.02.17
완전검색, 그리디  (0) 2023.02.15
정렬  (0) 2023.02.14
배열  (0) 2023.02.13