| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 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 | 
- 안드로이드 유닛 테스트 예시
 - jvm 작동 원리
 - rxjava disposable
 - 2022 플러터 설치
 - rxjava hot observable
 - 안드로이드 레트로핏 사용법
 - 2022 플러터 안드로이드 스튜디오
 - 클래스
 - android retrofit login
 - 멤버변수
 - 자바 다형성
 - 서비스 vs 쓰레드
 - Rxjava Observable
 - rxjava cold observable
 - 플러터 설치 2022
 - ar vr 차이
 - 객체
 - 안드로이드 라이선스 종류
 - 안드로이드 라이선스
 - 서비스 쓰레드 차이
 - 안드로이드 레트로핏 crud
 - jvm이란
 - ANR이란
 - 안드로이드 유닛테스트란
 - 안드로이드 os 구조
 - 안드로이드 유닛 테스트
 - 스택 자바 코드
 - android ar 개발
 - 스택 큐 차이
 - 큐 자바 코드
 
- Today
 
- Total
 
나만을 위한 블로그
[Algorithm] 백준 - 단어 공부 (1157) (Kotlin) 본문

가장 많이 사용된 알파벳 개수를 카운팅하는 문제다. 대소문자는 구분하지 않는다니까 대문자 또는소문자로 통일시켜서 처리하면 될 것이다.
바로 떠오르는 방법이라면 A~Z까지의 알파벳 26자를 담는 배열을 만들고, 입력값을 순회하면서 발견한 알파벳을 배열의 특정 인덱스에 담는 것이다.
그러나 배열 만드는 건 하겠지만 a나 d같은 알파벳인지 어떻게 확인해서 배열에서 해당 인덱스를 어떻게 업데이트할 것인지가 문제다.
우선 이렇게 풀 수 있다.
fun main() {
    val word = readln().uppercase()
    val count = IntArray(26)
    // 알파벳 개수 카운트
    for (char in word) {
        // 'A'를 빼면 0부터 시작하는 인덱스가 됨
        count[char - 'A']++
    }
    val maxCount = count.maxOrNull() ?: 0
    val maxCountAlphabets = count.count { it == maxCount }
    if (maxCountAlphabets > 1) {
        println("?")
    } else {
        val mostUsedIndex = count.indexOfFirst { it == maxCount }
        println('A' + mostUsedIndex) // 인덱스를 다시 문자로 변환
    }
}
readln()으로 입력값을 받은 다음 함수 체이닝으로 uppercase()를 호출해 입력값을 전부 대문자로 바꾼다. 당연히 처음부터 대문자였으면 uppercase()는 작동하지 않는다. 그리고 0을 26개 담기 위한 정수 배열 count를 선언했다.
이후 반복문으로 입력받은 String을 순회한다. 테스트 값인 baaa로 디버깅하면 순회할 때마다 B, A, A, A가 char에 할당되는 걸 볼 수 있다.
인텔리제이를 쓴다면 디버깅 시 각 대문자 옆에 뭐가 더 추가로 표시되는 걸 볼 수 있다.

B 옆에 66이란 숫자가 표시되고 있다. 이것은 아스키 코드라는 것인데 알파벳마다 대응되는 숫자 코드를 말한다.

아스키 코드가 무엇인지는 이 글에서 다루지 않는다. 궁금하면 구글링해서 찾아본다.
아무튼 이 아스키 코드를 활용하면 B에 대응하는 숫자가 66이란 걸 알 수 있다. A는 65고 B는 66, C는 67 순으로 65부터 1씩 증가하니 for 루프 안에서 char 변수로부터 'A'를 빼면 0, 1 같은 숫자가 나올 것이다.
B의 경우 66이니 'A'를 뺀다면 컴퓨터는 이 계산식을 66-65로 이해해서 1이란 결과를 리턴할 것이다.
또한 count[char - 'A']++ 를 통해 count 배열의 특정 인덱스에 1을 더하고 있으니 결과적으로 count 배열의 1번 인덱스가 1 증가되어 0 + 1 = 1이 된다.
한 차례 for문이 끝나면 배열에 담긴 값의 형태는 아래와 같다.
[ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
for문이 완전히 종료되면 count 배열에 담긴 값은 최종적으로 아래 형태가 된다.
[ 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
A가 3개 나왔으니 0번 인덱스가 3번 증가되어 3이 됐고 B는 1번만 나왔으니 1번 증가되어 1이 됐다. 나머지 알파벳들은 나온 적이 없으니 0 그대로다.
이렇게 하면 각 알파벳이 몇 번 나타났는지 구할 수 있다. 응용하면 전체 알파벳이 아닌 특정 구간의 알파벳 출현 빈도를 구하는 것도 가능하다.
그 후 maxOrNull() ?: 0으로 count 배열에서 가장 큰 값을 가져온다. 큰 값이 없으면 기본값인 0을 maxCount에 초기화하도록 엘비스 연산자를 쓰고 있음을 확인한다. 결국 maxCount엔 3이 담긴다.
그리고 count {} 함수로 가장 많이 나온 알파벳 개수를 확인한다. baaa의 경우 a만 3개 있기 때문에 maxCountAlphabets는 1이 된다.
다른 값인 Mississipi를 사용할 경우 배열에 담긴 값은 아래와 같다.
[ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0 ]
4가 2개 있다. 그럼 maxCount는 4가 되고, maxCountAlphabet에는 count 배열에서 4와 같은 값이 몇 개 있는지 센 count 함수의 결과값 2가 담긴다.
baaa는 maxCountAlphabets가 1이었기 때문에 else문이 작동해 해당 인덱스를 다시 char로 변환해 출력하지만 Mississipi는 maxCountAlphabets가 2라서 if문이 작동해 ?를 출력한다.
else문 안에선 'A'에 배열에서 maxCount가 처음 발견된 인덱스를 찾아 더한 다음 알파벳으로 바꿔 출력한다.
baaa에선 A가 3번 나오기 때문에 가장 많이 사용된 알파벳은 A고, A의 인덱스인 0에 'A'를 더하기 때문에 'A'를 출력하게 된다. A의 개수가 아닌 A의 인덱스에 더하는 것임에 주의한다.
'알고리즘 문제 풀이 > 백준' 카테고리의 다른 글
| [Algorithm] 백준 - 그룹 단어 체커 (1316) (Kotlin) (0) | 2025.10.01 | 
|---|---|
| [Algorithm] 백준 - 크로아티아 알파벳 (2941) (Kotlin) (0) | 2025.10.01 | 
| [Algorithm] 백준 - 팰린드롬인지 확인하기 (10988) (Kotlin) (0) | 2025.09.25 | 
| [Algorithm] 백준 - 킹, 퀸, 룩, 비숍, 나이트, 폰 (3003) (Kotlin) (0) | 2025.09.14 | 
| [Algorithm] 백준 - 그대로 출력하기 (11718) (Kotlin) (0) | 2025.09.13 |