String 클래스는 Java.lang 패키지로 제공되는 Java 문자열 클래스이다.

별도의 import 없이 사용이 가능한데, 아래와 같이 선언을 할 수 있다.

 

 

위 둘의 차이는 이후 알아보기로 하자.

String 클래스는 한 번 인스턴스가 생성되면 수정할 수 없다. (immutable object)

 

 

값의 변경은 불가능하지만, 새 String을 만들어 바꿀 수는 있다.

 

 

위 코드 중에서 char[]를 String으로 바꾸는 것에 주목해보자.

아래와 같이 2가지 방법으로 바꿀 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package String;
 
public class StringClass {
 
    public static void main(String[] args) {
        String str = "ABCDFFG";
        char[] temp_arr = str.toCharArray();
        System.out.println(temp_arr); // ABCDFFG
        temp_arr[4= 'E';
//        str = new String(temp_arr);
        str = String.valueOf(temp_arr);
        System.out.println(str); // ABCDEFG
    }
 
}
 
cs

 

즉, new String(char[] array) 혹은 String.valuOf(char[] array)를 이용!

 

그리고, 두 문자열이 같은지 비교하는 메서드로 equlas 메서드가 있는데, 왜 == 로는 비교를 할 수 없는지 살펴보자.

처음 String을 선언할 때 두 가지 방법이 있다는 것과 연결되는 내용이다.

 

 

두 방법의 차이는 리터럴로 선언하느냐, 인스턴스 객체를 생성하여 선언하느냐의 차이.

그 차이는 다음과 같다.

 

 

리터럴로 선언한 경우에는 두 변수가 같은 "text" 값을 가리키고 있다.

하지만, 인스턴스로 선언한 경우에는 서로 다른 객체를 생성하고 그 안에 "test"를 참조하고 있다.

따라서 아래와 같은 결과가 나타난다.

 

 

그러므로! String을 비롯한 primitive type이 아닌 경우에는 equals 메서드로 비교를 하도록 주의하자. 결국 코딩테스트를 준비하는 과정에서는 너무 당연하지만 ==  대신 equals를 써야하는 것에 주의하는 것이 중요하니까.

 

String 클래스가 제공하는 메서드들은 다양하지만, 그중 일부를 정리하자면,

 

 

 이어서 BOJ에서 문자열 관련 문제를 풀며 추가 정리하도록 하자.

 

 

Binary Search란 정렬되어 있는 데이터에서 원하는 값을 찾는 방법이다.

대상 데이터의 중앙값과 찾고자하는 값을 비교해 데이터의 크기를 절반씩 줄이면서 찾는데, 

이때 자료는 반드시 정렬된 상태여야 한다.(예를 들면, 오름/내림차순)

 

정렬방법에 대해 먼저, 대략적으로 얘기해보면,

1. 자료 중앙에 있는 원소를 고름

2. 중앙 원소의 값과 찾고자 하는 값을 비교

3. 찾고자 하는 값이 중앙 원소의 값보다 작으면 자료의 왼쪽 데이터에 대해서 새로 탐색하고,

크다면 자료의 오른쪽 데이터에 대해 새로 탐색한다.

4. 이를 반복한다.

 

핵심은 탐색의 범위를 반복적으로 반으로 줄이는 것이다.

 

이제 자세히 알아보자.

오름차순으로 정렬된 배열 arr = {2, 4, 7, 9, 11, 19, 23}이 있고, 이중 7을 검색하려고 한다.

먼저, 배열의 중앙 원소는 9이다.

직관적으로 중앙 원소가 무엇인지 알 수 있긴 하나, 그 값을 찾는 방법을 다시 말하자면,

맨 처음 index = 0, 마지막 index = 배열의 길이 - 1이므로 중앙 원소가 존재하는 index는 (0+ 배열의 길이 - 1) / 2가 된다.

즉, 배열 arr는 배열의 길이가 7이므로 중앙 원소가 존재하는 index는 (7-1) / 2 == 3.

따라서 중앙값은 arr[3]인 9이다.

이제 중앙 원소의 값(9)과 찾고자 하는 값(7)을 비교해보자.

찾고자 하는 값이 중앙값보다 왼쪽에 있으므로, 중앙값의 왼쪽 데이터에 대해 새로 탐색해야 한다.

이제, 맨 처음 index는 0, 맨 마지막 index는 2가 됐다.

이때의 중앙값은 index 1의 위치의 값인 4가 된다.

중앙값(4)와 찾는 값(7) 중에서 찾는 값이 더 크므로,

즉 찾는 값이 중앙값보다 오른쪽에 있으므로, 중앙값의 오른쪽 데이터에 대해 새로 탐색해야 한다.

그런데, 탐색 범위가 인덱스가 2인 값뿐이고, 찾는 값과 중앙값이 일치하므로 탐색을 성공한 것이다.

 

이제 코드를 작성하여 알아보도록 하자.

위와 같은 순서로,

1. 탐색의 대상이 되는 자료들이 정렬되어 있는 배열 arr[low]부터 arr[high]사이에 들어있다고 하자.

 - 배열의 길이가 N이라고 하면, low는 0번 인덱스, high는 N-1번 인덱스이다.

 

2. 중간값의 인덱스를 mid라고 하자. 

 - mid == (low+high) / 2이다.

 

3. 찾는 값(key값)이 arr[mid]보다 큰지, 작은지를 비교한다.

 - key < arr[mid]: 찾는 값이 중간값의 왼쪽에 존재하는 경우이므로 high를 mid-1로 만든다.

 - key > arr[mid]: 찾는 값이 중간값의 오른쪽에 존재하는 경우이므로 low를 mid+1로 만든다.

 - key == arr[mid]: 찾는 값을 찾음. 중간값을 return해주면 됨

 

4. low > high가 될 때까지 반복하면서 key값을 찾는다. 

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
import java.util.Arrays;
 
public class List_BianrySearch {
    
    static int[] arr = {4,9,11,23,2,19,7};
    public static void main(String[] args) {
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println(binarySearch(70, arr.length - 1));
        
    }
    
    // key - 구하고자 하는 값
    // mid - 중간값에 해당하는 인덱스
    // low - 0번 인덱스
    // high - (배열의 길이 - 1)번 인덱스
    
    static int binarySearch(int key, int low, int high) {
        
        //중간값
        int mid;
        while(low <= high) {
            mid = (low + high) / 2;
            if(key == arr[mid]) {
                return mid;
            } else if(key < arr[mid]) { //중간값의 왼쪽에 해당
                high = mid - 1//하나를 빼주면 왼쪽에서 가장 큰 값이 되니까
            } else { //중간값의 오른쪽에 해당
                low = mid + 1//하나를 더하면 오른쪽에서 가장 작은 값이 되니까
            }
        }
        return -1//탐색 실패
        
    }
    
}
 
cs

 

< 코드 작성++ >

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
import java.util.Arrays;
import java.util.Scanner;
 
public class Main {
 
    // 이진 탐색 소스코드 구현(반복문) -- 오름차순으로 정렬되어 있는 상태에서 이진 탐색!
    public static int binarySearch(int[] arr, int target, int start, int end) {
        /*
         * target: 찾고자 하는 값 start: 탐색 범위 내의 시작 인덱스 end: 탐색 범위 내의 끝 인덱스 mid: start와 end의 중간 위치 인덱스
         */
        while (start <= end) {
            int mid = (start + end) / 2;
 
            // target이 중간점에 위치할 경우 중간점의 인덱스를 반환한다.
            if (arr[mid] == target) {
                return mid;
            }
            // 오름차순 정렬상태이므로 target이 중간점보다 왼쪽에 위치한 경우 왼쪽 범위만 확인
            // end = mid - 1
            else if (arr[mid] > target) {
                return binarySearch(arr, target, start, mid - 1);
            }
            // target이 중간점보다 오른쪽에 위치한 경우 오른쪽 범위만 확인
            // start = mid + 1
            else {
                return binarySearch(arr, target, mid + 1, end);
            }
            // 못 찾은 경우 -1 반환
        }
        return -1;
 
    }
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 원소의 개수(n)와 찾고자 하는 값(target)을 입력받기
        int n = sc.nextInt();
        int target = sc.nextInt();
                
        // 전체 원소 입력 받기 + 오름차순 정렬하기
        int[] arr = new int[n];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = sc.nextInt();
        }
        Arrays.sort(arr);
        
        // 이진 탐색 수행 결과 출력
        int result = binarySearch(arr, target, 0, n-1);
        if(result == -1) {
            System.out.println("찾는 값이 존재하지 않습니다.");
        }
        else {
            System.out.println("찾는 값의 인덱스는 " + result + "입니다." );
        }
        
    }
}
cs

 

 

 

 

'알고리즘 및 코테' 카테고리의 다른 글

배열에 정수를 입력할 때마다 정렬하여 출력하기  (0) 2023.01.27
정렬 - Selection Sort  (0) 2023.01.10
정렬 - Bubble Sort  (0) 2023.01.09
선택 정렬(Selection Sort)는 배열의 원소 중에서 원하는 위치에 놓을 데이터를 찾아 선택하는 것

 

어떤 배열을 오름차순으로 정렬하고 싶다고 가정하고 설명하도록 한다.

int[] array = {5, 9, 1, 7, 2}; 인 배열 array가 있다고 하자.

정렬을 할 때마다 배열의 맨 앞부터의 위치들에 최솟값들이 하나씩 이동하게 되므로

이미 최솟값을 이동시킨 위치는 고려하지 않고, 그 다음 위치들 중에서 최솟값을 찾는다.

 

즉, 전체적인 과정을 설명하면,

 

1. 배열의 각 원소 중에서 최솟값을 찾고, 이를 array[0]과 자리를 바꾼다. (swap)

2. array[0]을 제외한 나머지 원소들 중에서 최솟값을 찾아 array[1]과 자리를 바꾼다.

3. array[2], array[3]....도 위의 방법대로 반복한다.

 

이때, (배열의 길이 - 1)만큼만 최솟값을 찾는 cycle을 진행하면 되는데, 

위의 예시에서 총 5개의 데이터 중에서 4개의 데이터를 정렬했다는 것은 이미 마지막 데이터는 정렬이 되었다는 의미이기 때문이다. (최솟값을 찾고 나머지 값들과 비교하여 정렬했으므로 2개씩 비교가 되었기 때문) 

 

이를 코드를 작성하여 비교해보자.

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.Arrays;
 
public class Selection_Sort {
    public static void main(String[] args) {
        // 선택정렬을 통해 오름차순으로 정렬
        int[] array = { 59172 };
        // 최솟값을 갖는 index를 찾아 그 index 자리의 값과 array[i]값을 바꿔준다.
        for (int i = 0; i < array.length - 1; i++) {
            int minIdx = i;
            for (int j = i + 1; j < array.length; j++) {
                if (array[minIdx] > array[j]) {
                    minIdx = j;
                }
            }
            int tmp = array[i];
            array[i] = array[minIdx];
            array[minIdx] = tmp;
        
        }
        System.out.println(Arrays.toString(array));
    }
}
 
cs

내림차순도 같은 논의로 진행해보면, (부등호의 방향만 반대)

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.Arrays;
 
public class Selection_Sort {
    public static void main(String[] args) {
        // 선택정렬을 통해 내림차순으로 정렬
        int[] array = { 59172 };
        // 최댓값을 갖는 index를 찾아 그 index 자리의 값과 array[i]값을 바꿔준다.
        for (int i = 0; i < array.length - 1; i++) {
            int maxIdx = i;
            for (int j = i + 1; j < array.length; j++) {
                if (array[maxIdx] < array[j]) {
                    maxIdx = j;
                }
            }
            int tmp = array[i];
            array[i] = array[maxIdx];
            array[maxIdx] = tmp;
        
        }
        System.out.println(Arrays.toString(array));
    }
}
 
cs

그 결과, {9, 7, 5, 2, 1}로 내림차순 정렬이 됨을 확인할 수 있다.

 

두 개의 인접한 원소(값)을 비교하여 정렬하는 것

버블 정렬에 대해 알아보기 위해 배열을 오름차순으로 나타내는 것을 기준으로 한다.

간단하게 말하면, 두개씩 값을 비교하고, 조건에 맞게 swap하는 것이다.

 

1. array[0]에서부터 비교(첫번째 cycle)

int[] array = { 1, 5, 9, 3, 7, 1, 0}; 인 배열 array을 오름차순으로 정렬하는 것을 예로 들어 설명하도록 한다.

먼저, array[0]과 array[1]을 비교했을 때, array[0] < array[1]이므로 swap할 필요가 없다.

같은 방식으로, array[1]와 array[2] 또한 swap할 필요가 없다.

이때, array[2] > array[3]이므로 두 원소를 swap해야 한다.

같은 방식으로 진행한 결과는 다음과 같다.

첫 번째 cycle 결과 배열 array는 { 1, 5, 3, 7, 1, 0, 9 }가 되었다.

 

2. 두번째 사이클

3. 세번째 사이클

4. 네번째 사이클

5. 다섯번째 사이클

6. 여섯번째 사이클

최종적으로 버블 정렬을 통해 오름차순 정렬을 한 결과는 {0, 1, 1, 3, 5, 7, 9}이다.

 

이제 코드를 작성하여 결과를 비교해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Arrays;
 
public class test {
 
    public static void main(String[] args) {
        // 오름차순
        int[] array = { 1539710 };
        int tmp; // swap을 위한 변수 선언
        // cycle은 (배열의 크기-1)만큼 진행된다.
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    tmp = array[j + 1];
                    array[j + 1= array[j];
                    array[j] = tmp;
                }
            }
        }
        System.out.println(Arrays.toString(array));
 
    }
 
}
 
cs

 

동일한 결과가 나타난다. 

 

내림차순으로 정렬하는 경우는 오름차순 정렬과 같은 논의이므로 부등호의 방향만 달리하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Arrays;
 
public class test {
 
    public static void main(String[] args) {
        // 내림차순
        int[] array = { 1539710 };
        int tmp; // swap을 위한 변수 선언
        // cycle은 (배열의 크기-1)만큼 진행된다.
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] < array[j + 1]) {
                    tmp = array[j + 1];
                    array[j + 1= array[j];
                    array[j] = tmp;
                }
            }
        }
        System.out.println(Arrays.toString(array));
 
    }
 
}
 
cs

 

결과는 { 9, 7, 5, 3, 1, 1, 0}.

Theme. 배열의 최댓값/최솟값 구하기

 

1. 최댓값

먼저, 배열 arr = {1, 5, 9, 3, 7, 1, 0}이 있다고 하자.

결론부터 말하면 배열의 첫번째 값을 최댓값이라고 가정하고, 이후 index마다의 값들과의 비교를 통해 더 큰 값이 존재하면 그 값을 최댓값으로 대입해주며 배열의 끝까지 비교해보는 것이다.

이제 자세히 알아보자.

int max = array[0];을 통해 배열의 첫번째 값을 max(최댓값)라고 가정해보자.

이제, 배열의 첫번째 값과 두번째 값을 비교해보자.

그 결과 array[1]인 5가 더 크므로 max의 값에 5를 대입해준다.(최댓값이 5인 상태)

같은 방식으로 한번더 진행한 결과는, 다음과 같다.

array[2]인 9가 5보다 크기 때문에 max의 값에 9를 대입해준다.(최댓값이 9인 상태)

이후 진행상황은, 

배열의 끝까지 비교한 결과 최댓값은 최종적으로 9가 된다.

이제 코드를 작성하여 결과를 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class test {
 
    public static void main(String[] args) {
        int[] array = { 1593710 }; // 배열 생성
        int max = array[0]; // 배열의 첫번째 값을 최댓값으로 가정
        for (int i = 0; i < array.length; i++) {
            if (max < array[i]) {
                max = array[i];
            }
        }
        System.out.println(max);
 
    }
 
}
 
cs

최댓값은 9가 나온다. 

 

2. 최솟값

최댓값을 구하는 방식과 같은 논의이나 단, 부등호의 방향이 바뀌는 것뿐이다. 

최댓값을 구할 때와 동일한 배열을 가지고 최솟값을 구하는 코드를 작성해보면,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class test {
 
    public static void main(String[] args) {
        int[] array = { 1593710 }; // 배열 생성
        int min = array[0]; // 배열의 첫번째 값을 최솟값으로 가정
        for (int i = 0; i < array.length; i++) {
            if (min > array[i]) {
                min = array[i];
            }
        }
        System.out.println(min);
 
    }
 
}
 
cs

최솟값은 0이 나온다.

 

Theme. SWEA 2068. 최대수 구하기

https://swexpertacademy.com/main/solvingProblem/solvingProblem.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

< Solution >

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
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
 
        for (int t = 1; t <= T; t++) {
            int[] arr = new int[10];
            for (int i = 0; i < 10; i++) {
                arr[i] = sc.nextInt();
            }
            int max = arr[0];
            for (int i = 0; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i];
                }
            }
            System.out.println("#" + t + " " + max);
        }
 
    }
 
}
 
cs

 

 

+ Recent posts