학습용 공간

관계형 데이터베이스(Relational Database)란 무엇인가?

# 관계형 데이터베이스의 정의 관계형 데이터베이스는 데이터를 테이블(table) 형태로 저장한 데이터베이스이다. 이 테이블은 키(key)와 값(value)의 관계를 나타낸다. 데이터들간의 종속성을 관계로 표현한 것이 관계형 데이터베이스이다. 각 테이블들은 이름을 가지며 행, 열, 그에 대응하는 값들을 구성요소로 갖는다. 관계형 데이터베이스에서 이러한 테이블들은 다른 테이블들과 관계를 갖고 있다. #관계형 데이터베이스의 특징 - 데이터의 분류, 정렬, 탐색의 속도가 빠르다. - 신뢰성이 높고, 데이터의 무결성을 보장한다. - 기존에 작성된 스키마를 수정하기 어렵다. - 데이터베이스의 부하를 분석하기 어렵다. #스키마란 무엇인가? 테이블을 디자인하기 위한 청사진이다. 데이터베이스의 데이터에 대한 유형과 제약..

DB 2020.08.05 starmk95

MySQL)Bitnami를 통해 MySQL 실행시키기 (cmd 이용)

1. 먼저 Bitnami폴더의 MySQL이 저장되어있는 경로로 이동한다. C:\Users\User>cd C:\Bitnami\wampstack-7.4.8-0\mysql\bin 2. 설치 당시 설정했던 암호를 입력하기 위한 명령어 C:\Bitnami\wampstack-7.4.8-0\mysql\bin>mysql -uroot -p 이때 -uroot에서 u는 user의 약자이고, root는 접속하고자 하는 사용자의 이름이다. 사용자 root는 관리자 느낌으로 최고 권한을 가지는 사용자를 의미한다. kim이라는 사용자로 mysql에 접근하기 위해서는 -ukim 이렇게 접근한다. -p의 p는 passward의 약자로 비밀번호를 입력받기 위한 명령어이다. 3. 암호 입력 4. 실행 완료

DB/MySQL 2020.08.05 starmk95

JAVA)10974번 모든 순열 - 브루트 포스, 순열

다음 순열을 구하는 알고리즘을 사용하여 구현했다. import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); StringBuilder sb = new StringBuilder(); int n = sc.nextInt(); int[] seq = new int[n]; for (int i=0;iA[i-1]을 만족하는 가장 작은 j를 찾는다. // (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 큰 값을 찾기) // 3. A[i-1]과 A[j]를 swap한다. // 4. A[i]부터 순열을 뒤집는다. // (i자리부터 오름차순으로 만들어줌 -> 해당 자리 ..

알고리즘/백준 알고리즘(JAVA) 2020.08.05 starmk95

JAVA)10973번 이전 순열 - 브루트 포스, 순열

import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] seq = new int[n]; for (int i=0;i seq[i]) { indexI = i; break; } } if (indexI == 0) { return null; } // 2단계 (j 찾기) int maxJ = -1; int indexJ = indexI; for (int j=indexI;j seq[j]) { if (maxJ == -1 || seq[j] > maxJ) { maxJ = seq[j]; indexJ = j; } } } // 3..

알고리즘/백준 알고리즘(JAVA) 2020.08.05 starmk95

JAVA)10972번 다음 순열 - 브루트 포스, 순열

import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] seq = new int[n]; for (int i=0;iA[i-1]을 만족하는 가장 작은 j를 찾는다. // (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 큰 값을 찾기) // 3. A[i-1]과 A[j]를 swap한다. // 4. A[i]부터 순열을 뒤집는다. // (i자리부터 오름차순으로 만들어줌 -> 해당 자리 기준 첫 순열로 만듬) static int[] next_permutation(int[] seq) { int indexI =..

알고리즘/백준 알고리즘(JAVA) 2020.08.05 starmk95

알고리즘)브루트 포스(Brute Force)와 순열(permutation)

# 브루트 포스 : 모든 경우의 수를 고려하는 방식이다. # 순열 : 임의의 수열을 각자 다른 순서로 섞어 세우는 경우의 수들을 의미 - 순서를 고려하는 문제에 사용되기 좋다. - 크기가 n인 수열에서 서로 다른 순열은 총 n!개가 있다. ex) A = [1, 2, 3] 순열들 : 123, 132, 213, 231, 312, 321 (사전순으로 나열함) 모든 순서를 다 고려해야하는 문제에서 순열이 사용된다. (그러므로 순열을 사용하는 것은 브루트 포스의 일종이라고 할 수 있다.) 순열을 문제에 응용하기 위해서는 특정 순열에서 다음 순열을 구하는 알고리즘이 필요하다. C++과 파이썬의 경우에는 다음 순열을 구하는 알고리즘이 자체적으로 구현되어 있지만, 자바에는 없다. (자바에서는 직접 구현해주어야 한다.)..

알고리즘 2020.08.05 starmk95

JAVA)15663번 N과 M (9) - 브루트 포스

import java.util.*; public class Main { static int[] nums; static int[] ans; static int[] cnt; static StringBuilder sb = new StringBuilder(); public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); nums = new int[n]; // 중복되는 수를 1개로 정리한 수열 ans = new int[m]; // 결과 저장할 배열 cnt = new int[n]; // 각 수열의 수의 중복이 몇 개가 있는지 저장한 배열 int[] temp =..

알고리즘/백준 알고리즘(JAVA) 2020.08.05 starmk95

JAVA)15651번 N과 M (3) - 브루트 포스

import java.io.*; import java.util.*; public class Main { static int[] ans; static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); int M = sc.nextInt(); ans = new int[M]; printSequence(0, N, M); bw.flush(); bw.close(); } // 브루트 포스 static void printSeq..

알고리즘/백준 알고리즘(JAVA) 2020.08.05 starmk95

JAVA)15650번 N과 M(2) - 브루트 포스

import java.util.*; public class Main { static boolean[] used; static int[] ans; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); int M = sc.nextInt(); used = new boolean[N+1]; ans = new int[M]; printSequence(0, 1, N, M); } // 브루트 포스 static void printSequence(int index, int start, int n, int m) { if (m == index) { // 재귀함수의 기저조건 : 마지막 자리 인덱스의 수까지..

알고리즘/백준 알고리즘(JAVA) 2020.08.05 starmk95

JAVA)15649번 N과 M (1) - 브루트 포스

import java.util.*; public class Main { static boolean[] used; static int[] ans; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); int M = sc.nextInt(); used = new boolean[N+1]; ans = new int[M]; printSequence(0, N, M); } // 브루트 포스 static void printSequence(int index, int n, int m) { if (m == index) { // 재귀함수의 기저조건 : 마지막 자리 인덱스의 수까지 구하면 수열 1개 완성 ..

알고리즘/백준 알고리즘(JAVA) 2020.08.04 starmk95

SQLD 자격증 준비

공부 교재 : SQL 전문가 가이드 출제 사이트에서 제공하는 퀴즈 : http://www.dbguide.net/da.db?cmd=snb13_list&boardGroupUid=6&boardConfigUid=81 :: DBguide.net :: 데이터베이스 구축 운영 종합정보 www.dbguide.net 팁 : https://inzoon.tistory.com/2 SQLD 자격증 시험 3주면 충분해! - 자격증 준비 비법 공개 ( 팁&예제&기출 ) SQL 개발자 자격시험(총 50문항 - 필기 50문항) 안녕하세요. 이슈를 모으다. 이모 인사드립니다. ( 이 글은 제 경험을 바탕으로 쓴 글이므로 준비하실때 참고하시길 바라며 작성하였습니다. ) ( SQLD � inzoon.tistory.com 교재 내용 정리 :..

DB/sqld 자격증 준비 2020.08.04 starmk95

JAVA)1748번 수 이어쓰기 1 - 브루트 포스

import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int num = sc.nextInt(); // 브루트 포스 // n의 최대값은 1억인데 그러면 수가 너무 많다. // 모든 경우를 고려하지 않고, 1의자리는 자리수를 1증가, 10의 자리는 2증가, 100의 자리는 3증가, ... // 하는 특성을 이용한다. int digits = (int)(Math.log10(num)+1); // 몇자리수인지 구하기 int len = 0; if (digits < 2) { // 한자리수가 들어왔을 때 len+=num; } else { // 두자리수 이상일 때 l..

알고리즘/백준 알고리즘(JAVA) 2020.08.04 starmk95
DB 2020.08.05 댓글 개 starmk95

관계형 데이터베이스(Relational Database)란 무엇인가?

# 관계형 데이터베이스의 정의

관계형 데이터베이스는 데이터를 테이블(table) 형태로 저장한 데이터베이스이다.

이 테이블은 키(key)값(value)의 관계를 나타낸다.

데이터들간의 종속성을 관계로 표현한 것이 관계형 데이터베이스이다.

 

각 테이블들은 이름을 가지며 행, 열, 그에 대응하는 값들을 구성요소로 갖는다.

관계형 데이터베이스에서 이러한 테이블들은 다른 테이블들과 관계를 갖고 있다.

 

#관계형 데이터베이스의 특징

 - 데이터의 분류, 정렬, 탐색의 속도가 빠르다.

 - 신뢰성이 높고, 데이터의 무결성을 보장한다.

 - 기존에 작성된 스키마를 수정하기 어렵다.

 - 데이터베이스의 부하를 분석하기 어렵다.

 

#스키마란 무엇인가?

테이블을 디자인하기 위한 청사진이다.

데이터베이스의 데이터에 대한 유형과 제약사항들을 스키마라고 한다.

예를 들어 필드가 특정 값을 받드시 가져야 한다는 조건이나 중복 값을 허용하지 않는다는 등의 제약조건들을 스키마라고 할 수 있다.

 

#열(column)

필드(field)라고도 불리며 항목의 속성을 나타내는 요소이다.

 

#행(row)

레코드(recoed)라고도 불리며, 각 데이터 항목들을 나타내는 요소이다.

번호 이름 학년 학과 성적
1 A 1 미디어학과 4.0
2 B 1 소프트웨어학과 3.8
3 C 2 사이버보안학과 3.4
4 D 4 수학과 4.4

위 표를 하나의 테이블이라고 한다면

번호, 이름, 학년, 학과, 성적을 나타내는 열들이 각각 하나의 필드이다.

4개의 데이터들이 각각 하나의 행(레코드)에 기록된 것을 확인할 수 있다.

 

DB/MySQL 2020.08.05 댓글 개 starmk95

MySQL)Bitnami를 통해 MySQL 실행시키기 (cmd 이용)

1. 먼저 Bitnami폴더의 MySQL이 저장되어있는 경로로 이동한다.

C:\Users\User>cd C:\Bitnami\wampstack-7.4.8-0\mysql\bin

 

2. 설치 당시 설정했던 암호를 입력하기 위한 명령어

C:\Bitnami\wampstack-7.4.8-0\mysql\bin>mysql -uroot -p

 

이때 -uroot에서 u는 user의 약자이고, root는 접속하고자 하는 사용자의 이름이다.

사용자 root는 관리자 느낌으로 최고 권한을 가지는 사용자를 의미한다.

kim이라는 사용자로 mysql에 접근하기 위해서는 

-ukim 이렇게 접근한다.

-p의 p는 passward의 약자로 비밀번호를 입력받기 위한 명령어이다.

 

3. 암호 입력

 

4. 실행 완료

알고리즘/백준 알고리즘(JAVA) 2020.08.05 댓글 개 starmk95

JAVA)10974번 모든 순열 - 브루트 포스, 순열

다음 순열을 구하는 알고리즘을 사용하여 구현했다.

 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
        int n = sc.nextInt();
        int[] seq = new int[n];
        for (int i=0;i<n;i++) seq[i] = i+1;
        do {
            for (int i=0;i<n;i++) {
                sb.append(seq[i] + " ");
            }
            sb.append("\n");
            seq = next_permutation(seq);
        } while (seq != null);
        System.out.print(sb);
    }

    // 다음 순열(permutation) 구하는 알고리즘(메소드)
    // 1. A[i-1] < A[i]를 만족하는 가장 큰 i를 찾는다.
    //   (뒤에 내림차순의 수만 남는 첫번째 자리를 구하기)
    // 2. j>=i이면서 A[j]>A[i-1]을 만족하는 가장 작은 j를 찾는다.
    //   (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 큰 값을 찾기)
    // 3. A[i-1]과 A[j]를 swap한다.
    // 4. A[i]부터 순열을 뒤집는다.
    //   (i자리부터 오름차순으로 만들어줌 -> 해당 자리 기준 첫 순열로 만듬)
    static int[] next_permutation(int[] seq) {
        int indexI = 0;
        // 1단계 (i 찾기)
        for (int i=seq.length-1;i>0;i--) {
            if (seq[i-1] < seq[i]) {
                indexI = i;
                break;
            }
        }
        if (indexI == 0) {
            return null;
        }
        // 2단계 (j 찾기)
        int minJ = -1;
        int indexJ = indexI;
        for (int j=indexI;j<seq.length;j++) {
            if (indexI < 1) break;
            if (seq[indexI-1] < seq[j]) {
                if (minJ == -1 || seq[j] < minJ) {
                    minJ = seq[j];
                    indexJ = j;
                }
            }
        }
        // 3단계 (swap)
        int temp = seq[indexI-1];
        seq[indexI-1] = seq[indexJ];
        seq[indexJ] = temp;

        // 4단계 (순열 뒤집기)
        int[] tempArr = new int[seq.length-indexI];
        for (int i=indexI;i<seq.length;i++) tempArr[i-indexI] = seq[i];
        Arrays.sort(tempArr);
        for (int i=indexI;i<seq.length;i++) seq[i] = tempArr[i-indexI];

        return seq;
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/10974

알고리즘/백준 알고리즘(JAVA) 2020.08.05 댓글 개 starmk95

JAVA)10973번 이전 순열 - 브루트 포스, 순열

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] seq = new int[n];
        for (int i=0;i<n;i++) seq[i] = sc.nextInt();
        int[] ans = prev_permutation(seq);
        if (ans == null) System.out.println(-1);
        else {
            for (int i=0;i<ans.length;i++) System.out.print(ans[i] + " ");
            System.out.println();
        }
    }

    // 이전 순열(permutation) 구하는 알고리즘(메소드)
    // 다음 순열을 구하는 알고리즘에서 부들호들만 반대로 바꾸어서 구현해주면 된다.
    // 1. A[i-1] > A[i]를 만족하는 가장 큰 i를 찾는다.
    //   (뒤에 오른차순의 수만 남는 첫번째 자리를 구하기)
    // 2. j<=i이면서 A[j]<A[i-1]을 만족하는 가장 큰 j를 찾는다.
    //   (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 작은 값을 찾기)
    // 3. A[i-1]과 A[j]를 swap한다.
    // 4. A[i]부터 순열을 뒤집는다.
    //   (i자리부터 내림차순으로 만들어줌 -> 해당 자리 기준 마지막 순열로 만듬)
    static int[] prev_permutation(int[] seq) {
        int indexI = 0;
        // 1단계 (i 찾기)
        for (int i=seq.length-1;i>0;i--) {
            if (seq[i-1] > seq[i]) {
                indexI = i;
                break;
            }
        }
        if (indexI == 0) {
            return null;
        }
        // 2단계 (j 찾기)
        int maxJ = -1;
        int indexJ = indexI;
        for (int j=indexI;j<seq.length;j++) {
            if (seq[indexI-1] > seq[j]) {
                if (maxJ == -1 || seq[j] > maxJ) {
                    maxJ = seq[j];
                    indexJ = j;
                }
            }
        }
        // 3단계 (swap)
        int temp = seq[indexI-1];
        seq[indexI-1] = seq[indexJ];
        seq[indexJ] = temp;

        // 4단계 (순열 뒤집기)
        int[] tempArr = new int[seq.length-indexI];
        for (int i=indexI;i<seq.length;i++) tempArr[i-indexI] = seq[i];
        int k = seq.length-indexI-1;
        for (int i=indexI;i<seq.length;i++) {
            seq[i] = tempArr[k];
            k-=1;
        }
        return seq;
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/10973

알고리즘/백준 알고리즘(JAVA) 2020.08.05 댓글 개 starmk95

JAVA)10972번 다음 순열 - 브루트 포스, 순열

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] seq = new int[n];
        for (int i=0;i<n;i++) seq[i] = sc.nextInt();
        int[] ans = next_permutation(seq);
        if (ans == null) System.out.println(-1);
        else {
            for (int i=0;i<ans.length;i++) System.out.print(ans[i] + " ");
            System.out.println();
        }
    }

    // 다음 순열(permutation) 구하는 알고리즘(메소드)
    // 1. A[i-1] < A[i]를 만족하는 가장 큰 i를 찾는다.
    //   (뒤에 내림차순의 수만 남는 첫번째 자리를 구하기)
    // 2. j>=i이면서 A[j]>A[i-1]을 만족하는 가장 작은 j를 찾는다.
    //   (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 큰 값을 찾기)
    // 3. A[i-1]과 A[j]를 swap한다.
    // 4. A[i]부터 순열을 뒤집는다.
    //   (i자리부터 오름차순으로 만들어줌 -> 해당 자리 기준 첫 순열로 만듬)
    static int[] next_permutation(int[] seq) {
        int indexI = 0;
        // 1단계 (i 찾기)
        for (int i=seq.length-1;i>0;i--) {
            if (seq[i-1] < seq[i]) {
                indexI = i;
                break;
            }
        }
        if (indexI == 0) {
            return null;
        }
        // 2단계 (j 찾기)
        int minJ = -1;
        int indexJ = indexI;
        for (int j=indexI;j<seq.length;j++) {
            if (indexI < 1) break;
            if (seq[indexI-1] < seq[j]) {
                if (minJ == -1 || seq[j] < minJ) {
                    minJ = seq[j];
                    indexJ = j;
                }
            }
        }
        // 3단계 (swap)
        int temp = seq[indexI-1];
        seq[indexI-1] = seq[indexJ];
        seq[indexJ] = temp;

        // 4단계 (순열 뒤집기)
        int[] tempArr = new int[seq.length-indexI];
        for (int i=indexI;i<seq.length;i++) tempArr[i-indexI] = seq[i];
        Arrays.sort(tempArr);
        for (int i=indexI;i<seq.length;i++) seq[i] = tempArr[i-indexI];

        return seq;
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/10972

알고리즘 2020.08.05 댓글 개 starmk95

알고리즘)브루트 포스(Brute Force)와 순열(permutation)

# 브루트 포스 : 모든 경우의 수를 고려하는 방식이다.


# 순열 : 임의의 수열을 각자 다른 순서로 섞어 세우는 경우의 수들을 의미

 - 순서를 고려하는 문제에 사용되기 좋다.
 - 크기가 n인 수열에서 서로 다른 순열은 총 n!개가 있다.
ex) A = [1, 2, 3]
순열들 : 123, 132, 213, 231, 312, 321 (사전순으로 나열함)
모든 순서를 다 고려해야하는 문제에서 순열이 사용된다. 

(그러므로 순열을 사용하는 것은 브루트 포스의 일종이라고 할 수 있다.)

순열을 문제에 응용하기 위해서는 특정 순열에서 다음 순열을 구하는 알고리즘이 필요하다.
C++과 파이썬의 경우에는 다음 순열을 구하는 알고리즘이 자체적으로 구현되어 있지만,  자바에는 없다.

(자바에서는 직접 구현해주어야 한다.)

ex) N=4이고 A = [1, 2, 3, 4]이면 
순열은 총 4!(24)개
1234 2134 ...
1243 2143
1324 2314
1342 2341
1423 2413
1432 2431

순열들은 앞자리수부터 사전순으로 나열됨.
앞이 1인 모든 경우 -> 앞이 2인 모든 경우 -> 앞이 3인 모든 경우 -> ...

 

# 첫번째 순열과 마지막 순열의 특성
첫 순열 : 1234 - 오름차순임
마지막 순열 : 4321 - 내림차순임

ex )  7236541의 다음 순열 구하기 
723 / 6541 - 6541은 내림차순임 (내림차순이라는 것은 해당 자리에서 시작 기준 마지막 순열이라는 뜻)
그러므로 해당 순열의 다음 순열은 72?????다 된다.
다음 순열은 3 뒤에 위치한 수 중 3과 가장 적은 차이로 큰 수가 ? 중 첫자리에 오게 된다.
3 뒤의 6541 중 위 조건에 해당하는 수는 4이다.
(이를 찾는 시간복잡도 = O(N))
마지막 순열 다음은 첫 순열이 오게 되므로
72 / 4 / 1356 (1356은 오름차순으로 해당 자리 기준의 첫 순열이다.)
(첫 순열 만드는 것도 시간복잡도가 O(N)이다.)

그러므로 7236541의 다음 순열은 7241356이다.

위 과정을 4개의 단계들로 정리하면 (i는 내림차순 부분의 첫 자리 인덱스라고 할 때)


1. A[i-1] < A[i]를 만족하는 가장 큰 i를 찾는다. 

   (뒤에 내림차순의 수만 남는 첫번째 자리를 구하기)


2. j>=i이면서 A[j]>A[i-1]을 만족하는 가장 작은 j를 찾는다. 

   (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 큰 값을 찾기)


3. A[i-1]과 A[j]를 swap한다.


4. A[i]부터 순열을 뒤집는다. 

   (i자리부터 오름차순으로 만들어줌 -> 해당 자리 기준 첫 순열로 만듬)

1과 2는 O(n), 3은 O(1), 4는 O(n)
그러므로 총 시간 복잡도는  O(n) + O(n) + O(n) + O(n) = O(n)이다.

모든 순열을 구하기 위해서는 첫 순열부터 마지막 순열에 다다를 때까지(n!-1번) 위 알고리즘(O(n))을 반복해주어야 한다.
그러므로 모든 순열을 구하는 총 시간복잡도는 O(n*n!)이 된다.

 

팩토리얼 값은

3! = 6,

... ,

10! = 3,628,800 (3천만~)

11! = 39,916,800 (약 4억)

이므로 

순열은 수열의 크기의 입력이 11보다 작은 경우에 주로 사용된다.

(이보다 크면 모든 순열을 고려하는데 이미 적어도 4초 이상이 걸리므로 좋지 않음)

 

# 다음 순열을 구하는 알고리즘 (마지막 순열이 입력으로 들어오면 -1 출력)

 - next_permutation 메소드가 해당 알고리즘을 구현한 메소드이다.

 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] seq = new int[n];
        for (int i=0;i<n;i++) seq[i] = sc.nextInt();
        int[] ans = next_permutation(seq);
        if (ans == null) System.out.println(-1);
        else {
            for (int i=0;i<ans.length;i++) System.out.print(ans[i] + " ");
            System.out.println();
        }
    }

    // 다음 순열(permutation) 구하는 알고리즘(메소드)
    // 1. A[i-1] < A[i]를 만족하는 가장 큰 i를 찾는다.
    //   (뒤에 내림차순의 수만 남는 첫번째 자리를 구하기)
    // 2. j>=i이면서 A[j]>A[i-1]을 만족하는 가장 작은 j를 찾는다.
    //   (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 큰 값을 찾기)
    // 3. A[i-1]과 A[j]를 swap한다.
    // 4. A[i]부터 순열을 뒤집는다.
    //   (i자리부터 오름차순으로 만들어줌 -> 해당 자리 기준 첫 순열로 만듬)
    static int[] next_permutation(int[] seq) {
        int indexI = 0;
        // 1단계 (i 찾기)
        for (int i=seq.length-1;i>0;i--) {
            if (seq[i-1] < seq[i]) {
                indexI = i;
                break;
            }
        }
        if (indexI == 0) {
            return null;
        }
        // 2단계 (j 찾기)
        int minJ = -1;
        int indexJ = indexI;
        for (int j=indexI;j<seq.length;j++) {
            if (indexI < 1) break;
            if (seq[indexI-1] < seq[j]) {
                if (minJ == -1 || seq[j] < minJ) {
                    minJ = seq[j];
                    indexJ = j;
                }
            }
        }
        // 3단계 (swap)
        int temp = seq[indexI-1];
        seq[indexI-1] = seq[indexJ];
        seq[indexJ] = temp;

        // 4단계 (순열 뒤집기)
        int[] tempArr = new int[seq.length-indexI];
        for (int i=indexI;i<seq.length;i++) tempArr[i-indexI] = seq[i];
        Arrays.sort(tempArr);
        for (int i=indexI;i<seq.length;i++) seq[i] = tempArr[i-indexI];

        return seq;
    }
}

# 이전 순열을 구하는 알고리즘 (다음 순열을 구하는 알고리즘에서 부등호들을 모두 반대로 바꾸어주면 됨)

 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] seq = new int[n];
        for (int i=0;i<n;i++) seq[i] = sc.nextInt();
        int[] ans = prev_permutation(seq);
        if (ans == null) System.out.println(-1);
        else {
            for (int i=0;i<ans.length;i++) System.out.print(ans[i] + " ");
            System.out.println();
        }
    }

    // 이전 순열(permutation) 구하는 알고리즘(메소드)
    // 다음 순열을 구하는 알고리즘에서 부들호들만 반대로 바꾸어서 구현해주면 된다.
    // 1. A[i-1] > A[i]를 만족하는 가장 큰 i를 찾는다.
    //   (뒤에 오른차순의 수만 남는 첫번째 자리를 구하기)
    // 2. j<=i이면서 A[j]<A[i-1]을 만족하는 가장 큰 j를 찾는다.
    //   (i 뒤에 있는 수들 중 i자리 값과 차이가 가장 적게 작은 값을 찾기)
    // 3. A[i-1]과 A[j]를 swap한다.
    // 4. A[i]부터 순열을 뒤집는다.
    //   (i자리부터 내림차순으로 만들어줌 -> 해당 자리 기준 마지막 순열로 만듬)
    static int[] prev_permutation(int[] seq) {
        int indexI = 0;
        // 1단계 (i 찾기)
        for (int i=seq.length-1;i>0;i--) {
            if (seq[i-1] > seq[i]) {
                indexI = i;
                break;
            }
        }
        if (indexI == 0) {
            return null;
        }
        // 2단계 (j 찾기)
        int maxJ = -1;
        int indexJ = indexI;
        for (int j=indexI;j<seq.length;j++) {
            if (seq[indexI-1] > seq[j]) {
                if (maxJ == -1 || seq[j] > maxJ) {
                    maxJ = seq[j];
                    indexJ = j;
                }
            }
        }
        // 3단계 (swap)
        int temp = seq[indexI-1];
        seq[indexI-1] = seq[indexJ];
        seq[indexJ] = temp;

        // 4단계 (순열 뒤집기)
        int[] tempArr = new int[seq.length-indexI];
        for (int i=indexI;i<seq.length;i++) tempArr[i-indexI] = seq[i];
        int k = seq.length-indexI-1;
        for (int i=indexI;i<seq.length;i++) {
            seq[i] = tempArr[k];
            k-=1;
        }
        return seq;
    }
}
알고리즘/백준 알고리즘(JAVA) 2020.08.05 댓글 개 starmk95

JAVA)15663번 N과 M (9) - 브루트 포스

import java.util.*;

public class Main {
    static int[] nums;
    static int[] ans;
    static int[] cnt;
    static StringBuilder sb = new StringBuilder();
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        nums = new int[n]; // 중복되는 수를 1개로 정리한 수열
        ans = new int[m]; // 결과 저장할 배열
        cnt = new int[n]; // 각 수열의 수의 중복이 몇 개가 있는지 저장한 배열
        int[] temp = new int[n];
        for (int i=0;i<n;i++) {
            temp[i] = sc.nextInt();
        }
        Arrays.sort(temp);
        int x = temp[0];
        int index = 0;
        int c = 1;
        for (int i=1;i<n;i++) {
            if (x == temp[i]) {
                c+=1; // 중복되는 수 있음
            } else { // 중복되는 수가 더 이상 없고, 새로운 수가 들어오면
                nums[index] = x; // 해당 수를 배열에 저장하고
                cnt[index] = c; // 같은 수가 총 몇개가 있었는지 저장
                c = 1; // 다음 수의 검사를 위해 1로 초기화
                index+=1; // 다음 수로 접근 할 수 있게 인덱스로 사용하는 변수 +1
                x = temp[i]; // 다음 수를 검사하기 위해 x에 자장
            }
        }
        // 마지막 수는 배열에 저장 처리가 안되므로 반복문 밖에서 따로 처리
        nums[index] = x;
        cnt[index] = c;
        n = index+1; // 인덱스+1을 해주어야 중복을 제거한 수들의 총 개수가 된다.
        makeSeq(n, m, 0);
        System.out.print(sb);
    }
    // 브루트 포스
    static void makeSeq(int n, int m, int index) {
        if (index == m) {
            for (int x : ans) {
                sb.append(x + " ");
            }
            sb.append("\n");
            return;
        }
        for (int i=0;i<n;i++) {
            if (cnt[i] > 0) {
                ans[index] = nums[i];
                cnt[i]-=1;
                makeSeq(n, m, index+1);
                cnt[i]+=1;
            }
        }
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/15663

알고리즘/백준 알고리즘(JAVA) 2020.08.05 댓글 개 starmk95

JAVA)15651번 N과 M (3) - 브루트 포스

import java.io.*;
import java.util.*;

public class Main {
    static int[] ans;
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int M = sc.nextInt();
        ans = new int[M];
        printSequence(0, N, M);
        bw.flush();
        bw.close();
    }

    // 브루트 포스
    static void printSequence(int index, int n, int m) throws IOException {
        if (m == index) { // 재귀함수의 기저조건 : 마지막 자리 인덱스의 수까지 구하면 수열 1개 완성
            for (int x : ans) {
                bw.write(x + " ");
            }
            bw.write("\n");
            return;
        }
        for (int i = 1; i <= n; i++) {
            ans[index] = i; // 해당 차례의 인덱스에 수를 널기
            printSequence(index + 1, n, m); // 다음 인덱스 자리에 올 숫자들을 확인
        }
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/15651

알고리즘/백준 알고리즘(JAVA) 2020.08.05 댓글 개 starmk95

JAVA)15650번 N과 M(2) - 브루트 포스

import java.util.*;

public class Main {
    static boolean[] used;
    static int[] ans;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int M = sc.nextInt();
        used = new boolean[N+1];
        ans = new int[M];
        printSequence(0, 1, N, M);
    }

    // 브루트 포스
    static void printSequence(int index, int start, int n, int m) {
        if (m == index) { // 재귀함수의 기저조건 : 마지막 자리 인덱스의 수까지 구하면 수열 1개 완성
            for (int x : ans) {
                System.out.print(x + " ");
            }
            System.out.println();
            return;
        }
        for (int i=start;i<=n;i++) {
            if (used[i] == false) { // 수를 사용하지 않은 경우에만 확인
                ans[index] = i; // 해당 차례의 인덱스에 수를 널기
                used[i] = true; // 중복 확인용
                printSequence(index+1, i+1, n, m); // 다음 인덱스 자리에 올 숫자들을 확인
                used[i] = false; // 위 재귀가 끝나면 해당 수가 들어가는 경우들은 모두 고려한 것임
            }
        }
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/15650

알고리즘/백준 알고리즘(JAVA) 2020.08.04 댓글 개 starmk95

JAVA)15649번 N과 M (1) - 브루트 포스

import java.util.*;

public class Main {
    static boolean[] used;
    static int[] ans;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int M = sc.nextInt();
        used = new boolean[N+1];
        ans = new int[M];
        printSequence(0, N, M);
    }

    // 브루트 포스
    static void printSequence(int index, int n, int m) {
        if (m == index) { // 재귀함수의 기저조건 : 마지막 자리 인덱스의 수까지 구하면 수열 1개 완성
            for (int x : ans) {
                System.out.print(x + " ");
            }
            System.out.println();
            return;
        }
        for (int i=1;i<=n;i++) {
            if (used[i] == false) { // 수를 사용하지 않은 경우에만 확인
                ans[index] = i; // 해당 차례의 인덱스에 수를 널기
                used[i] = true; // 중복 확인용 
                printSequence(index+1, n, m); // 다음 인덱스 자리에 올 숫자들을 확인
                used[i] = false; // 위 재귀가 끝나면 해당 수가 들어가는 경우들은 모두 고려한 것임
            }
        }
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/15649

DB/sqld 자격증 준비 2020.08.04 댓글 개 starmk95

SQLD 자격증 준비

알고리즘/백준 알고리즘(JAVA) 2020.08.04 댓글 개 starmk95

JAVA)1748번 수 이어쓰기 1 - 브루트 포스

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        // 브루트 포스
        // n의 최대값은 1억인데 그러면 수가 너무 많다.
        // 모든 경우를 고려하지 않고, 1의자리는 자리수를 1증가, 10의 자리는 2증가, 100의 자리는 3증가, ...
        // 하는 특성을 이용한다.
        int digits = (int)(Math.log10(num)+1); // 몇자리수인지 구하기
        int len = 0;
        if (digits < 2) { // 한자리수가 들어왔을 때
            len+=num;
        } else { // 두자리수 이상일 때
            len += (num - Math.pow(10, digits-1) + 1)*digits;
            digits-=1;
            for (int i=0;i<digits;i++) {
                len+=9*Math.pow(10, i)*(i+1);
            }
        }
        System.out.println(len);
    }
}

 

문제 출처 : https://www.acmicpc.net/problem/1748