posted by 귀염둥이채원 2019. 3. 13. 16:55

# 문제링크

https://www.acmicpc.net/problem/2042


# 알고리즘

- Segment Tree를 사용해서 풀어야 한다.

- https://palyoung.tistory.com/64


# 풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package segment;
 
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static int N, M, K;
    static int arr[];
    public static void main(String[] args) throws IOException {
        //System.setIn(new FileInputStream("src\\sample.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder sb = new StringBuilder();
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        
        arr = new int[N];
        int a=0, b=0, c=0;
        
        for (int i=0; i<N; i++) {
            arr[i] = Integer.parseInt(br.readLine());
        }
        
        SegmentTree seg = new SegmentTree(arr, N);
        //seg.print();
        
        for (int i=0; i<M+K; i++) {
            st = new StringTokenizer(br.readLine());
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());
            c = Integer.parseInt(st.nextToken());
            
            // segment tree 업데이트
            if (a == 1) {
                seg.update(b-1, c, 10, N-1);
            }
            // segment tree에서 구간의 합 
            else if (a == 2) {
                sb.append(seg.query(b-1, c-110, N-1)+"\n");
            }
        }
        System.out.println(sb);
    }
}
 
class SegmentTree {
    long SegmentTreeArr[];    // segment tree node 데이터
    
    SegmentTree(int arr[], int N) {
        SegmentTreeArr = new long[N*4];
        init(arr, 0, N-11);
    }
    
    // Leaf Node가 N개인 Segment Tree 생성
    // node 의 왼쪽 자식은 node*2, 오른쪽 자식은 node*2+1
    long init(int arr[], int left, int right, int node) {
        // node가 리프 노드인 경우
        if (left == right) return SegmentTreeArr[node] = arr[left];
        int mid = (left+right)/2;
        return SegmentTreeArr[node] = init(arr, left, mid, node*2+ init(arr, mid+1, right, node*2+1);
    }
    
    // Segment Tree를 갱신하고 노드 구간의 합을 구한다.
    long update(int index, int value, int node, int nodeLeft, int nodeRight) {
        // index가 Node 구간에 포함되지 않는 경우
        if (index < nodeLeft || index > nodeRight) return SegmentTreeArr[node];
        
        // node가 리프 노드인 경우
        if (nodeLeft == nodeRight)  return SegmentTreeArr[node] = value; 
        
        int mid = (nodeLeft + nodeRight)/2;
        return SegmentTreeArr[node] = update(index, value, node*2, nodeLeft, mid) + update(index, value, node*2+1, mid+1, nodeRight); 
    }
    
    // Segment Tree의 구간 합을 구한다.
    long query(int left, int right, int node, int nodeLeft, int nodeRight) {
        // 두 구간이 겹치지 않는 경우
        if (left > nodeRight || right < nodeLeft) return 0;
        
        // [left, right]가 [nodeLeft, nodeRight]를 포함하는 경우
        if (left <= nodeLeft && right >= nodeRight) return SegmentTreeArr[node];
        
        int mid = (nodeLeft + nodeRight)/2;
        return query(left, right, node*2, nodeLeft, mid) + query(left, right, node*2+1, mid+1, nodeRight); 
    }
    
    void print() {
        for (int i=0; i<SegmentTreeArr.length; i++) {
            System.out.printf("%d, ", SegmentTreeArr[i]);
        }
        System.out.println();
    }
}
cs


'PS(Problem Solving) > Segment Tree' 카테고리의 다른 글

최솟값과 최댓값  (0) 2019.03.14
[BOJ]10868. 최솟값  (0) 2019.03.13
posted by 귀염둥이채원 2019. 3. 11. 11:33

# 디렉토리 삭제

$ git rm -r --cached {directory name}

* git rm --> 원격 저장소와 로컬 저장소에 있는 파일을 삭제한다.

* git rm --cached --> 원격 저장소에 있는 파일을 삭제한다. 로컬 저장소에 있는 파일은 삭제하지 않는다.


# git commit

$ git commit -m "remove {directory name} directory"


# git push

$ git push origin master

'Tool > git' 카테고리의 다른 글

Git commit --amend로 마지막 커밋 수정하기  (0) 2019.02.08
git submodule이란?  (0) 2019.02.08
git commit --amend 오류  (0) 2019.01.24
posted by 귀염둥이채원 2019. 3. 4. 21:20

TreeSet, TreeMap은 이진 트리(binary tree)를 이용해서 계층적 구조(Tree 구조)를 가지면서 객체를 저장합니다.


# TreeSet

- 하나의 노드는 노드 값인 value와 왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성

- TreeSet에 객체를 저장하면 자동으로 정렬되는데 부모값과 비교해서 낮은 것은 왼쪽 노드에, 높은 것은 오른쪽 노드에 저장

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class TreeSetExam1 {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<Integer>();
         
        for (int i = 1; i <= 10; i++) {
            treeSet.add(new Integer(i*10));
        }
 
        Integer score = null;
 
        score = treeSet.first();
        System.out.println("가장 낮은 점수: " + score);
 
        score = treeSet.last();
        System.out.println("가장 높은 점수: " + score);
 
        score = treeSet.lower(new Integer(90));
        System.out.println("90점 아래 점수: " + score);
 
        score = treeSet.higher(new Integer(90));
        System.out.println("90점 위 점수: " + score);
    }
}
 
/********* 결과 *********
가장 낮은 점수: 10
가장 높은 점수: 100
90점 아래 점수: 80
90점 위 점수: 100
*/
cs


# TreeMap

- TreeSet과 차이점은 키와 값이 저장된 Map.Entry를 저장한다는 점

- TreeMap에 객체를 저장하면 자동으로 정렬되는데, 기본적으로 부모 키값과 비교해서 키 값이 낮은 것은 왼쪽 노드에, 키 값이 높은 것은 오른쪽 노드에 Map.Entry에 저장

★★API 그림 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.util.Map;
import java.util.TreeMap;
 
public class TreeMapExam1 {
    public static void main(String[] args) {
        TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
 
        treeMap.put(new Integer(90), "Jack");
        treeMap.put(new Integer(77), "Mike");
        treeMap.put(new Integer(82), "Jolie");
        treeMap.put(new Integer(93), "Sminoph");
        treeMap.put(new Integer(67), "Neil");
        treeMap.put(new Integer(55), "Max");
 
        Map.Entry<Integer, String> entry = null;
 
        entry = treeMap.firstEntry();
        System.out.println("가장 낮은 점수: " + entry.getKey() + "-" + entry.getValue());
 
        entry = treeMap.lastEntry();
        System.out.println("가장 높은 점수: " + entry.getKey() + "-" + entry.getValue());
 
        entry = treeMap.lowerEntry(new Integer(95));
        System.out.println("95점 아래 점수: " + entry.getKey() + "-" + entry.getValue());
 
        while (!treeMap.isEmpty()) {
            entry = treeMap.pollFirstEntry();
            System.out.println(entry.getKey() + "-" + entry.getValue() + " (남은 객체 수: " + treeMap.size() + ")");
        }
    }
}
 
/********* 결과 *********
가장 낮은 점수: 55-Max
가장 높은 점수: 93-Sminoph
95점 아래 점수: 93-Sminoph
55-Max (남은 객체 수: 5)
67-Neil (남은 객체 수: 4)
77-Mike (남은 객체 수: 3)
82-Jolie (남은 객체 수: 2)
90-Jack (남은 객체 수: 1)
93-Sminoph (남은 객체 수: 0)
*/
cs


# 참고사이트

★★https://palpit.tistory.com/657

https://lapan.tistory.com/61

https://hackersstudy.tistory.com/26

https://12bme.tistory.com/91

posted by 귀염둥이채원 2019. 3. 4. 18:20

# 이진검색트리 (Binary Search Tree) 개념

- 이진탐색(binary search)과 연결리스트(linked list)를 결합한 자료구조

- 데이터는 정렬이 되어 있어야하며, 탐색 작업에 효율적

- 한 노드에 자식이 최대 2개까지만 존재할 수 있는 트리


1. 모든 노드의 키는 유일하다. 

  - 중복된 데이터를 갖는 노드가 없다는 뜻이다. 

  - 여기서 키의 의미는 노드 안에 들어 있는 데이터 값을 의미한다.


2. 왼쪽 서브 트리의 키들은 루트의  키보다 작다. 

  - 예를 들어 루트노드의 데이터가 5라고 하면, 왼쪽 서브트리에는 무조건 5보다 작은 값들만 존재해야 한다.


3. 오른쪽 서브 트리의 키들은 루트의 키보다 크다.  

  - 위와 같은 원리로 오른쪽에는 루트의 데이터 값보다 더 큰 값들만 존재한다.

4. 왼쪽과 오른쪽 서브 트리도 이진 탐색 트리이다. 

  - 순환적으로 정의되었다는 뜻이다.

  - 즉 왼쪽 서브트리로 내려가든, 오른쪽 서브트리로 내려가든 동일한 법칙이 적용된다는 뜻이다.


# 이진검색트리 (Binary Search Tree) 예시

- 전화번호부에서 전화번호를 찾거나 

- 서점에서 책을 찾거나 

- 지도에서 목적지를 찾는것


# 이진검색트리 (Binary Search Tree) 목적

- 이진탐색의 경우 탐색에 소요되는 계산복잡성은 O(logn)으로 빠르지만 자료 입력, 삭제가 불가능합니다.

- 연결리스트의 경우 자료 입력, 삭제에 필요한 계산복잡성은 O(1)로 효율적이지만 

  탐색하는 데에는 O(n)의 계산복잡성이 발생합니다.

- 이진탐색트리 핵심 연산인 탐색, 삽입, 삭제의 계산복잡성은 모두 O(h) 입니다.


# 이진검색트리 (Binary Search Tree) 용어

successor: 삭제 대상 노드의 오른쪽 서브트리 가운데 최소값

redecessor: 삭제 대상 노드의 왼쪽 서브트리 가운데 최대값


# 시간복잡도 정리

삽입, 삭제, 탐색 모두 최선의 경우(트리의 균형이 잘 잡혀있는 경우, 즉, 왼쪽 오른쪽 자식이 잘 분배되어 있는 경우) O(logN)의 시간복잡도를 가지고, 최악의 경우 (자식 노드가 한쪽으로 쏠려 있는 경우) O(N)이다.

최악의 경우에는 경우에는 균형잡힌 이진 검색트리(balanced binary search tree)으로 사용하면 좋다.


# Binary Searh Tree의 3가지 순회방법

참고 강의: https://www.youtube.com/watch?v=QN1rZYX6QaA&index=2&list=PLjSkJdbr_gFY8VgactUs6_Jc9Ke8cPzZP

- Inorder (Left -> Root -> Right)

- Preorder (Root -> Left -> Right)

- Postorder (Left -> Right -> Root)


# 이진검색트리 (Binary Search Tree) 정리

- array와 비교시 tree는 add/remove 연산 속도가 빠르다.

- balanced binary search tree의 경우 insert/delete가 O(log N)이다. (자바에서 TreeMap으로 구현)


# 유투브 영상

https://www.youtube.com/watch?v=9ZZbA2iPjtM&t=3s

https://www.youtube.com/watch?v=9ZZbA2iPjtM&index=8&list=PLjSkJdbr_gFY8VgactUs6_Jc9Ke8cPzZP


# 참고사이트

★★https://kingpodo.tistory.com/29

★★http://ivis.kr/images/a/a5/2018_DS_ch09.pdf

★★https://songeunjung92.tistory.com/31

★★https://swalloow.tistory.com/35

https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%ED%83%90%EC%83%89_%ED%8A%B8%EB%A6%AC

https://ratsgo.github.io/data%20structure&algorithm/2017/10/22/bst/

https://wkdtjsgur100.github.io/binary-search-tree/

https://mattlee.tistory.com/30

https://kka7.tistory.com/78

posted by 귀염둥이채원 2019. 3. 3. 22:41

# 큐(Queue)란?

- 먼저 삽입된 데이터가 가장 먼저 제거되는 선입선출(FIFO - First In First Out) 형태의 자료구조


# 큐(Queue) API

* Object element(): 저장된 요소를 불러옴

* boolean offer(Object o ): Queue에 객체 저장 ( true:성공, false:실패) 반환

* Object peek(): 저장된 객체를 반환 / 없을경우 Null 을 반환

* Object poll(): 객체를 꺼내온다 / 꺼낸객체는 사라짐


# 큐(Queue) 클래스 사용법

LinkedList 클래스로 Queue를 인스턴스화하여 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.util.LinkedList;
import java.util.Queue;
 
public class Main {
    static Queue <Integer> q;
    public static void main(String[] args) {
        // queue는 LinkedList 클래스로 선언한다.
        q = new LinkedList<Integer>();
        
        // queue 초기화
        q.clear();
        
        // queue에 데이터 1 삽입
        q.add(1);
        
        // queue에 데이터 5 삽입
        q.add(5);
        
        // queue의 size 출력
        System.out.println("queue size: " +q.size());
        
        // queue에서 데이터 확인 및 제거
        System.out.println("data(pool): " +q.poll());
        
        // queue에서 데이터 확인
        System.out.println("data(peek): " +q.peek());
        
        // queue에서 데이터 확인 및 제거
        System.out.println("data(pool): " +q.poll());
        
        // queue에 데이터가 존재하는지 확인
        if (q.isEmpty()) {
            System.out.println("queue is empty");
        }
    }
}
 
/*********** 결과 ***************
queue size: 2
data(pool): 1
data(peek): 5
data(pool): 5
queue is empty
*/
cs


# 큐(Queue) 구현 - 배열 사용

# 문제

주어진 N(2<= N <=100)개의 수를 순서대로 Queue에 넣은 후 하나씩 꺼내 화면에 출력


# 입력

2

5

1 2 3 4 5 

5 4 2 3 1


# 출력

#1 1 2 3 4 5 

#2 5 4 2 3 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import java.io.FileInputStream;
import java.util.Scanner;
 
class Main2 {
    static final int MAX_N = 100;
 
    static int front;
    static int rear;
    static int queue[] = new int[MAX_N];
 
    static void queueInit() {
        front = 0;
        rear = 0;
    }
 
    static boolean queueIsEmpty() {
        return (front == rear);
    }
 
    static boolean queueIsFull() {
        if ((front + 1) % MAX_N == rear) {
            return true;
        } else {
            return false;
        }
    }
 
    static boolean queueEnqueue(int value) {
        if (queueIsFull()) {
            System.out.print("queue is full!");
            return false;
        }
        queue[front] = value;
        front++;
        if (front >= MAX_N) {
            front = MAX_N;
        }
 
        return true;
    }
 
    static Integer queueDequeue() {
        if (queueIsEmpty()) {
            System.out.print("queue is empty!");
            return null;
        }
 
        Integer value = new Integer(queue[rear]);
 
        rear++;
        if (rear >= MAX_N) {
            rear = MAX_N;
        }
        return value;
    }
 
    public static void main(String arg[]) throws Exception {
        //System.setIn(new FileInputStream("c:\\boj\\sample.txt"));
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
 
        for (int test_case = 1; test_case <= T; test_case++) {
            int N = sc.nextInt();
 
            queueInit();
            for (int i = 0; i < N; i++) {
                int value = sc.nextInt();
                queueEnqueue(value);
            }
 
            System.out.print("#" + test_case + " ");
 
            while (!queueIsEmpty()) {
                Integer value = queueDequeue();
                if (value != null) {
                    System.out.print(value.intValue() + " ");
                }
            }
            System.out.println();
        }
        sc.close();
    }
}
cs


# 참고사이트

https://hyeonstorage.tistory.com/263

https://swalloow.tistory.com/32

https://gamjatwigim.tistory.com/72

posted by 귀염둥이채원 2019. 3. 3. 22:10

# 문제링크

https://www.acmicpc.net/problem/10828


# 문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.


명령은 총 다섯 가지이다.

push X: 정수 X를 스택에 넣는 연산이다.

pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.

size: 스택에 들어있는 정수의 개수를 출력한다.

empty: 스택이 비어있으면 1, 아니면 0을 출력한다.

top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.


# 풀이1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.Stack;
 
public class Main {
    static int N;
    static Stack <Integer> stk;
    
    static void func(String inputStr) {
        String strCommand[];
        if (inputStr.contains("push")) {
            strCommand = inputStr.split(" ");
            int number = Integer.parseInt(strCommand[1]);
            stk.push(number);
        }
        else if (inputStr.equals("pop")) {
            if (stk.size() > 0) {
                System.out.println(stk.pop());
            }
            else {
                System.out.println(-1);
            }
        }
        else if (inputStr.equals("size")) {
            System.out.println(stk.size());
        }
        else if (inputStr.equals("empty")) {
            if (stk.isEmpty()) {
                System.out.println(1);
            }
            else {
                System.out.println(0);
            }
        }
        else if (inputStr.equals("top")) {
            if (stk.isEmpty()) {
                System.out.println(-1);
            }
            else {
                System.out.println(stk.peek());
            }
        }
    }
    
    public static void main(String[] args) throws FileNotFoundException {
        Scanner sc = new Scanner(System.in);
 
        stk = new Stack <Integer>();
        stk.clear();
        
        N = sc.nextInt();
 
        for (int i=0; i<=N; i++) {
            func(sc.nextLine());
        }
        sc.close();
    }
}
cs


# 풀이2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Main {
    static int N;
    static Stack <Integer> stk;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        
        stk = new Stack <Integer>();
        stk.clear();
        
        N = Integer.parseInt(br.readLine());
        for (int i=0; i<N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            
            switch (st.nextToken()) {
                case "push":
                    stk.push(Integer.parseInt(st.nextToken()));
                    break;
                case "pop":
                    if (stk.size() > 0) {
                        sb.append(stk.pop() + "\n");
                    }
                    else {
                        sb.append("-1" + "\n");
                    }
                    break;
                case "size":
                    sb.append(stk.size() + "\n");
                    break;
                case "empty":
                    if (stk.isEmpty()) {
                        sb.append(1 + "\n");
                    }
                    else {
                        sb.append(0 + "\n");
                    }
                    break;
                case "top":
                    if (stk.isEmpty()) {
                        sb.append(-1 + "\n");
                    }
                    else {
                        sb.append(stk.peek() + "\n");
                    }
                    break;
            }
        }
        
        System.out.println(sb);
    }
}
cs


# 회고

풀이 2에서 BufferedReader, StringBuilder를 사용해서 성능을 개선하였다.

(풀이1: 140ms, 풀이2: 436ms)


split 대신 StringTokenizer를 사용하여 문자열을 파싱함


# 풀이 참고

https://www.acmicpc.net/source/10582053

https://www.acmicpc.net/source/7385991

https://www.acmicpc.net/source/8726490

posted by 귀염둥이채원 2019. 3. 3. 21:58

# 자바(java) 프로그램 코드의 시간 측정 방법

https://palyoung.tistory.com/41


long beforeTime = System.currentTimeMillis();

****** 소스 코드 ******

System.out.println("count= " + count);

long afterTime = System.currentTimeMillis();

long secDiffTime = (afterTime - beforeTime);

System.out.println("시간차이(msec) : " + secDiffTime);


# 시간복잡도(Time Complexity), 빅오(Big-O)표기법이란?

https://palyoung.tistory.com/37


# String to int, int to String 변환

https://palyoung.tistory.com/52


# String값을 int형의 값으로 바꾸는 방법

int numInt = Integer.parseInt(numStr);


# int형의 값을 String으로 바꾸는 방법

String numStr2 = String.valueOf(numInt);


# ArrayList 사용법

https://palyoung.tistory.com/50


# StringTokenizer 사용법 정리

https://palyoung.tistory.com/54


# String vs StringBuffer vs StringBuiler

https://palyoung.tistory.com/53

StringBuilder가 성능이 좋다.


# Scanner vs BufferedReader 차이

https://palyoung.tistory.com/55

BufferedReader가 성능이 좋다.



'PS(Problem Solving) > 공통' 카테고리의 다른 글

백준 사이트 정리  (0) 2019.03.01
알고리즘 소스 템플릿  (0) 2019.02.27
알고리즘 문제 풀이 템플릿  (0) 2019.02.27
알고리즘 학습 관련 자료 모음  (0) 2019.02.27
posted by 귀염둥이채원 2019. 3. 3. 21:48

# Scanner

- Scanner는 사용하기 편리지만 속도가 느리다.

- 공란과 줄바꿈을 입력값의 경계로 사용하며, 입력받은 즉시 자료형이 확정된다.


# BufferedReader

- 일반적으로 라인단위로 입력을 받는다.

- 입력받은 값이 String 타입이므로 타입변환이 필요해서 불편함이 존재

- throws Exception 혹은 try ~ catch 를 이용해서 Exception을 따로 처리가 필요


하지만 많은 양의 데이터를 입력받을경우 BufferedReader를 통해 입력받는 것이 효율면에서 훨씬 낫습니다.알고리즘 문제를 풀때는 BufferedReader를 사용하는 것이 좋다.


# 성능 차이 참고

https://algospot.com/forum/read/2496/


# Scanner 예제 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Scanner;
 
public class ScannerPractice {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        // Integer Type Input
        int intValue = sc.nextInt();
 
        // Long Type Input
        long longValue = sc.nextLong();
        
        // Double Type Input
        double doubleValue = sc.nextDouble();
 
        // String Type Input
        String strValue = sc.next();
 
        // Boolean Type Input
        boolean boolValue = sc.nextBoolean();
    }
}
 
cs


# BufferedReader 예제 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class BufferedReaderTest {
    // BufferedReader는 Exception이 처리를 따로 해줘야 하기 때문에 throws를 해주거나 
    // try ~ catch로 예외처리를 해줘야합니다.
    public static void main(String[] args) throws Exception {
        // BufferedReader 객체 생성
        // new InputStreamReader 및 System.in
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
        // StringTokenizer 객체 선언
        StringTokenizer st = null;
 
        // String Line이므로 Integer.parseInt를 이용하여 형변환해야함
        int n = Integer.parseInt(br.readLine());
 
        // "1 3 5 7" 식으로 공란 포함 String Line일시 StringTokenizer 이용
        int[] arrays = new int[n + 1];
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= n; i++) {
            // 배열에다 토큰을 하나씩 불러서 입력해줌
            arrays[i] = Integer.parseInt(st.nextToken());
        }
    }
}
 
cs


# BufferedReader + StringBuiler 예제 소스

알고리즘 풀때는 한꺼번에 모아서 입력을 받고 한꺼번에 모아서 출력하는 것이 성능이 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class Main {
    public static void main(String[] args) throws IOException{
 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
 
        int N = Integer.parseInt(br.readLine());
        int[] arr = new int[10010];
 
        for (int i = 0; i< N;i++){
            arr[Integer.parseInt(br.readLine())]++;
        }
 
        for(int i =0; i<= 10000; i++){
            while(arr[i] != 0){
                sb.append(""+i+"\n");
                arr[i]--;
            }
            
        }
        System.out.println(sb.toString());
    }
}
 
 
출처: https://lifeignite.tistory.com/34 [게임 && PS ignite]
cs


# 참고사이트

https://cocomo.tistory.com/507

https://coding-factory.tistory.com/251

https://mygumi.tistory.com/236

https://code0xff.tistory.com/5

https://lifeignite.tistory.com/34

posted by 귀염둥이채원 2019. 3. 3. 21:18

자바는 String을 token단위로 끊어주는 StringTokenizer 클래스를 제공한다.


# 생성자

1. StringTokenizer(String str)

- str : 분석할 문자열

- 기본 분리 문자를 사용합니다. 

  기본 분리 문자에는 공백문자, 탭문자, 개행문자, 캐리지리턴문자가 있습니다.


2. StringTokenizer(String str , String delim)

- str : 분석할 문자열

- delim : 분리 문자로 사용할 문자


3. StringTokenizer(String str , String delim , boolean returnDelims)

- str : 분석할 문자열

- delim : 분리 문자로 사용할 문자

- returnDelims : 분리 문자까지 분리해서 출력할지 여부


# 주요함수

countTokens(): 토큰의 갯수를 리턴한다.

nextToken(): 다음 토큰을 리턴한다. 이전 토큰은 제거한다.

nextToken(String delim): 구획문자(delimiter)를 delim으로 바꾼 후 바뀐 다음 토큰을 리턴한다.

hasMoreTokens(): 리턴할 다음 토큰이 있으면 true를 다음 토큰이 없으면 false를 리턴한다.


# 예제 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Main {
    public static void main(String[] args) {
            String str = "this is my string"
            StringTokenizer st = new StringTokenizer(str); 
            System.out.println(st.countTokens()); 
            
            while(st.hasMoreTokens()) { 
                System.out.println(st.nextToken()); 
            }
            System.out.println(st.countTokens());
    }
}
 
/*********** 결과 ***************
4
this
is
my
string
0
*/
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.StringTokenizer;
 
public class Main {
    public static void main(String[] args) {
        String str = "this%^is%^my%^string"
        
        StringTokenizer st = new StringTokenizer(str,"%^");
        System.out.println(st.nextToken()); 
        System.out.println(st.nextToken());
        System.out.println(st.nextToken());
        System.out.println(st.nextToken());
    }
}
 
/*********** 결과 ***************
this
is
my
string
*/
cs


# 참고사이트

https://arer.tistory.com/48

https://dlfma1985.tistory.com/52

posted by 귀염둥이채원 2019. 3. 3. 20:52

# String

- String 객체는 한번 생성되면 할당된 메모리 공간이 변하지 않는다.

  + 연산자 또는 concat 메서드를 사용할 경우 새로운 String 객체를 생성 --> 메모리 낭비

- 문자열 연산이 많은 경우 성능이 좋지 않다.

- synchronization(동기화) 없이도 데이터가 안전하게 공유 가능 (Thread-safe)


# StringBuffer

- mutable 가변클래스 &&  synchronization(동기화) 보장, 멀티 스레드 보장

- 문자열에 대해 변경을 시도할 경우 새로운 객체를 생성하지 않고 기존문자열을 수정하여 문자열을 변경


# StringBuilder

- mutable 가변클래스 && 단일 스레드에서만 보장

- 문자열에 대해 변경을 시도할 경우 새로운 객체를 생성하지 않고 기존문자열을 수정하여 문자열을 변경


정리하자면, 읽기용이나 공유용도로 문자열을 사용해야 한다면, String 타입을 ...

(단일 문자열 참조일 경우)


문자열 수정을 해야 하면서 멀티 스레드 환경이라면, StringBuffer를 ... 

(동기화 기능 O  -> 멀티 스레드 환경에서 안정성 보장)


문자열 수정을 해야 하면서 싱글 스레드 환경이라면, StringBuffer를 ... 

(동기화 기능 X  -> 싱글 스레드 환경에서 사용 권장)


# String/StringBuffer/StringBuilder 성능비교 포스팅 참조

https://kutar37.tistory.com/51


3개의 성능을 비교해보면 StringBuilder > StringBuffer > String 순으로 StringBuilder가 제일 빠르다.

알고리즘 문제를 푸는 경우에는 StringBuilder를 사용하자!!

StringBuffer/StringBuiler 클래스는 여러가지 문자열 조작을 위한 api를 제공한다.


# StringBuffer/StringBuiler에서 reverse()로 문자열 뒤집기가 가능하다.

StringBuilder aa = new StringBuilder("ABCDE");

System.out.printf("%s\n", aa.reverse());  --> EDCBA

System.out.printf("%s\n", aa); --> EDCBA


# 문자열 비교시 StringBuiler -> String으로 변환해서 해야함!!

Ex) if(input.toString().equals(reverse.toString())


# StringBuiler 사용 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package Blog;
 
public class Main {
    public static void main(String[] args) {
        // 1. 생성
        StringBuilder sb = new StringBuilder();
        
        // 2. 문자열 추가
        sb.append("안녕하세요 ");
        sb.append("오늘은").append(2).append("월 입니다.");
        System.out.println(sb);
        
        // 3. 값 원하는 위치(index)에 삽입.
        sb.insert(6"useStringBuilder!!!");
        System.out.println(sb);
        
        // 4. 삭제
        sb.delete(1113);
        System.out.println(sb);
        
        // 5. 문자열을 역순으로 만들기
        sb.reverse();
        System.out.println(sb);
    }
}
 
/********** 결과 ***************
안녕하세요 오늘은2월 입니다.
안녕하세요 useStringBuilder!!!오늘은2월 입니다.
안녕하세요 useStngBuilder!!!오늘은2월 입니다.
.다니입 월2은늘오!!!redliuBgntSesu 요세하녕안
*/
cs


# 참고사이트

https://limkydev.tistory.com/119

https://hackersstudy.tistory.com/12

https://handcoding.tistory.com/44

https://jsnote.tistory.com/22