1427번: 소트인사이드
첫째 줄에 정렬하고자하는 수 N이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이다.
www.acmicpc.net
1. 문제 추상화
주어진 수의 각 자리수를 내림차순으로 정렬하시오
2. 알고리즘
1. 수를 문자열로 받는다.
2. 문자열의 길이만큼 정수 배열을 생성한다.
3. 문자열의 각 문자를 배열에 정수로 저장한다.
4. 내림차순 정렬을 한다.
1번 - 3번까지의 코드는 아래와 같다.
// 1. 수를 문자열로 받기
public static void setInputData() {
Scanner sc = new Scanner(System.in);
input = sc.next();
}
// 2. 문자열의 길이만큼 정수배열 생성하기
public static void createArr() {
arr = new int[input.length()];
}
// 3. 문자열의 각 문자를 정수로 배열에 저장하기
public static void initializeArr() {
for(int i =0; i< arr.length; i++) {
arr[i] = input.charAt(i) - '0';
}
}
위 과정이 완료되면 배열을 내림차순 정렬을 하면된다. 버블 정렬, 퀵 정렬, 병합 정렬, 카운팅 정렬, 힙 정렬을 사용했다. 정렬 알고리즘은 아래 포스팅에 정리하였다. 아래 포스팅은 모두 오름차순을 기준으로 설명하고 있으니 유념하기를 바란다.
[알고리즘] 버블정렬 향상 시키기
버블정렬은 가장 쉽고 이해하기 쉬운 정렬이다. 그러나 시간복잡도가 O(n2)이어서 효율이 좋지 않다. 7개의 수를 일차원 배열에 저장하였다. 이제 버블정렬을 사용하여 오름차순으로 바꾸어 보
lordofkangs.tistory.com
[알고리즘] 퀵 정렬 (Quick Sort)
퀵 정렬(Quick Sort)은 이름 그대로 정렬을 빠르게 하는 알고리즘이다. 그러나 버블정렬에 비해 빠를 뿐, 이름만큼 가장 빠른 정렬 알고리즘은 아니다. 퀵 정렬(Quick Sort) 알고리즘이란? 정렬 알고리
lordofkangs.tistory.com
[알고리즘] 합병 정렬 ( Merge Sort )
시간복잡도 O(N2)과 O(NlogN)의 차이는 분할정복을 하느냐 안 하느냐의 차이이다. N개의 수를 N번 비교하는게 아니라 (버블정렬) N개의 수를 분할한 수만큼 비교하는 것이다. (퀵정렬) [알고리즘] 버
lordofkangs.tistory.com
[알고리즘] 힙 정렬 ( Heap Sort )
힙 정렬( Heap Sort )은 성능 좋은 정렬 알고리즘이지만 원리를 이해하기 쉽지 않다. 그 이유는 완전 이진 트리를 이용하기 때문이다. [자료구조] 완전이진트리 배열에 저장하기 완전 이진 트리를
lordofkangs.tistory.com
[JAVA] 백준 10989번 수 정렬하기 3 : 카운팅 정렬 (Counting Sort)
10989번: 수 정렬하기 3 첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 숫자가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다. www.acmicpc.net 1. 문제 추상화 N
lordofkangs.tistory.com
3. 코드
< 버블 정렬 >
public static void doBubbleSort() {
for(int i =0; i<arr.length-1;i++) {
int lastExchangeNum = 0;
int lastExchangeIndex = 0;
for(int j = arr.length-1; j > i; j--) {
if(arr[j] > arr[j-1]) {
swap(j);
lastExchangeNum++;
lastExchangeIndex = j-1;
}
}
if(lastExchangeNum == 0) break;
else i = lastExchangeIndex;
}
}
public static void swap(int value) {
int tmp = arr[value];
arr[value] = arr[value-1];
arr[value-1] = tmp;
}
< 퀵정렬 >
퀵정렬은 재귀함수가 아닌 Stack을 이용한 반복문을 사용하여 풀었다.
[알고리즘] 퀵정렬 향상시키기 ( 스택 )
[알고리즘] 퀵 정렬 (Quick Sort) 퀵 정렬(Quick Sort)은 이름 그대로 정렬을 빠르게 하는 알고리즘이다. 그러나 버블정렬에 비해 빠를 뿐, 이름만큼 가장 빠른 정렬 알고리즘은 아니다. 퀵 정렬(Quick Sort
lordofkangs.tistory.com
public static void doQuickSort(int left, int right) {
Stack<Integer> leftStack = new Stack<Integer>();
Stack<Integer> rightStack = new Stack<Integer>();
leftStack.push(left);
rightStack.push(right);
while(!leftStack.isEmpty()) {
int leftPointer = left = leftStack.pop();
int rightPointer = right = rightStack.pop();
int pivot = arr[(left+right)/2];
while(leftPointer <= rightPointer) {
while( arr[leftPointer] > pivot ) leftPointer++;
while( arr[rightPointer] < pivot ) rightPointer--;
if(leftPointer <= rightPointer) {
swap(leftPointer++,rightPointer--);
}
}
if( left < rightPointer ) {
leftStack.push(left);
rightStack.push(rightPointer);
}
if( leftPointer < right ) {
leftStack.push(leftPointer);
rightStack.push(right);
}
}
}
public static void swap(int leftPointer, int rightPointer) {
int tmp = arr[leftPointer];
arr[leftPointer] = arr[rightPointer];
arr[rightPointer] = tmp;
}
< 병합 정렬 >
public static void doMergeSort(int left, int right) {
if(left < right) {
int center = ( left + right )/2;
doMergeSort(left, center);
doMergeSort(center+1, right);
applyMerge(left,right);
}
}
public static void applyMerge(int left, int right) {
int[] leftArr = new int[right-left+1];
int center = ( right + left )/2;
int leftSize = 0;
int leftPointer = 0;
int rightPointer = center + 1;
int arrPointer = left;
for(int i=left; i<=center; i++) {
leftArr[leftSize++] = arr[i];
}
for(arrPointer = left; arrPointer <= right; arrPointer++) {
if(leftPointer < leftSize && rightPointer <= right) {
arr[arrPointer] = leftArr[leftPointer] > arr[rightPointer] ? leftArr[leftPointer++] : arr[rightPointer++];
}else {
break;
}
}
while(leftPointer < leftSize) {
arr[arrPointer++] = leftArr[leftPointer++];
}
}
< 힙 정렬 >
public static void doHeapSort(){
int lastChildIndex = arr.length-1;
int lastParentIndex = ( lastChildIndex - 1)/2;
for(int i = lastParentIndex; i>=0; i--) {
makeHeap(i,lastChildIndex);
}
for(int i = arr.length-1; i>0; i--) {
swap(0,i);
makeHeap(0,i-1);
}
}
public static void makeHeap(int pivotIndex, int lastChildIndex) {
int parentValue = arr[pivotIndex];
int parentIndex = pivotIndex;
int childIndex = 0;
for(parentIndex = pivotIndex; parentIndex < (lastChildIndex + 1)/2; parentIndex = childIndex) {
int leftChildIndex = 2*parentIndex + 1;
int rightChildIndex = leftChildIndex + 1;
if(rightChildIndex > lastChildIndex) childIndex = leftChildIndex;
else childIndex = arr[leftChildIndex] < arr[rightChildIndex] ? leftChildIndex : rightChildIndex;
if( parentValue < arr[childIndex] ) break;
else arr[parentIndex] = arr[childIndex];
}
arr[parentIndex] = parentValue;
}
public static void swap(int root, int lastIndex) {
int tmp = arr[root];
arr[root] = arr[lastIndex];
arr[lastIndex] = tmp;
}
<카운팅 정렬>
public static void doCountingSort(){
int[] countingArr = new int[getMaxValue()+1];
for(int value : arr) {
countingArr[value]++;
}
int arrPointer = 0;
for(int i=countingArr.length-1; i >= 0; i--) {
if(countingArr[i] == 0) continue;
for( int j = 0; j < countingArr[i]; j++) {
arr[arrPointer++] = i;
}
}
}
public static int getMaxValue() {
int max = 0;
for(int value : arr) {
if( value > max ) max = value;
}
return max;
}
< 전체 코드 >
각 정렬 알고리즘 코드를 제외한 나머지 부분은 모두 동일하다. 버블 정렬 기준으로 한 전체 코드이다.
import java.util.Scanner;
//버블정렬
public class Main {
public static String input;
public static StringBuilder sb;
public static int[] arr;
public static void main(String[] args) {
setInputData(); // 1. 문자열로 수 입력받기
createArr(); // 2. 문자열 길이로 정수배열 생성하기
initializeArr(); // 3. 문자열의 각 문자 정수로 배열에 저장하기
doBubbleSort(); // 4. 배열 내림차순 정렬하기
printArr(); // 5. 배열 출력하기
}
public static void setInputData() {
Scanner sc = new Scanner(System.in);
input = sc.next();
}
public static void createArr() {
arr = new int[input.length()];
}
public static void initializeArr() {
for(int i =0; i< arr.length; i++) {
arr[i] = input.charAt(i) - '0';
}
}
public static void doBubbleSort() {
for(int i =0; i<arr.length-1;i++) {
int lastExchangeNum = 0;
int lastExchangeIndex = 0;
for(int j = arr.length-1; j > i; j--) {
if(arr[j] > arr[j-1]) {
swap(j);
lastExchangeNum++;
lastExchangeIndex = j-1;
}
}
if(lastExchangeNum == 0) break;
else i = lastExchangeIndex;
}
}
public static void swap(int value) {
int tmp = arr[value];
arr[value] = arr[value-1];
arr[value-1] = tmp;
}
public static void printArr() {
sb = new StringBuilder();
for( int value : arr) {
sb.append(value);
}
System.out.println(sb.toString());
}
}
'문제풀이 > Sorting' 카테고리의 다른 글
[JAVA] 백준 10814번 나이순 정렬 : 단어정렬 (0) | 2021.09.07 |
---|---|
[JAVA] 백준 11650번 좌표 정렬하기 : 이차원 배열 (0) | 2021.08.16 |
[JAVA] 백준 2108번 통계학 : 정렬 (0) | 2021.08.09 |
[JAVA] 백준 10989번 수 정렬하기 3 : 카운팅 정렬 (Counting Sort) (0) | 2021.08.05 |
[JAVA] 백준 2751번 수 정렬하기2 : 병합 정렬( Merger Sort ) (0) | 2021.08.05 |