Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 게임프로그래밍
- 백준
- TPS
- 구조체포인터
- dfs
- 개발자
- 오늘의에러
- 미라클모닝
- 언리얼로그
- C++
- 프로그래밍
- 게임개발
- 코딩
- unreal
- 재귀함수
- UE5
- 자료구조
- 코딩테스트
- permutation
- 구조체
- 커스텀로그
- 탐색기법
- 얌얌코딩
- 내가해냄
- 개발
- 연산자오버로딩
- 링크드리스트
- fstring
- c++자료구조
- 언리얼
Archives
- Today
- Total
All is well
[백준/C++] 10808(알파벳 개수) (아스키 코드 / 범위 기반 for문 / constexpr / 삼항연산자) 본문
C++/BAEKJOON
[백준/C++] 10808(알파벳 개수) (아스키 코드 / 범위 기반 for문 / constexpr / 삼항연산자)
D0YUN 2025. 3. 8. 15:55
https://www.acmicpc.net/problem/10808
내가 해냄
#include <bits/stdc++.h>
using namespace std;
string s; // 입력받을 문자열 선언
// 알파벳 개수가 기억이 안나서 아스키코드 값을 이용하여 배열 크기 지정
// 소문자 개수만큼 배열을 선언하여 각 알파벳의 개수를 저장
int cnt['z' - 'a' + 1] = {0};
int main()
{
/*
배열의 크기 확인 방법:sizeof(배열) / sizeof(배열의 첫 번째 요소)
- 배열 전체 크기를 각 요소의 크기로 나누어 개수를 구할 수 있음.
*/
// cout << sizeof(cnt) / sizeof(cnt[0]) << "\n"; // 배열 크기 확인용 코드 (디버깅용)
// 문자열 s를 입력받는다
cin >> s;
/*
입력받은 문자열을 순회하면서 각 알파벳의 등장 횟수를 카운트
- s[i]는 문자(char)이며, 이를 'a'와의 차이를 이용해 배열의 인덱스로 변환
- 'a'는 ASCII 값 97이므로, 'a'~'z'를 0~25 범위의 인덱스로 변환 가능
- 예: 'b' - 'a' → 1, 'z' - 'a' → 25
*/
for (int i = 0; i < s.size(); i++)
cnt[s[i] - 'a']++;
/*
배열에 저장된 각 알파벳의 등장 횟수를 출력
- 범위 기반 for문을 사용하여 cnt 배열의 모든 값을 출력
- 값들 사이에는 공백을 출력하여 가독성을 높임
*/
for(int i : cnt) cout << i << " ";
return 0;
}
사용한 핵심 개념
// 배열을 이용한 카운팅 (Counting Array)
- `cnt` 배열을 활용하여 각 알파벳의 등장 횟수를 저장하는 방식이다.
- 공간 복잡도가 O(1)로 빠른 조회 및 업데이트가 가능하다.
- 해시 테이블(`unordered_map`) 대신 고정된 크기의 배열을 활용하여 더 빠르게 동작한다.
- 코드에서 활용
int cnt[26] = {0}; // 26개의 공간을 갖는 배열 선언
for (int i = 0; i < s.size(); i++)
cnt[s[i] - 'a']++; // 해당 알파벳 인덱스 증가
// ASCII 코드 값 이용 (s[i] - 'a')
- 문자 'a'부터 'z'까지의 ASCII 코드 값을 활용하여 배열의 인덱스로 변환하는 기법이다.
- 'a'의 ASCII 값은 97, 'b'는 98, ..., 'z'는 122이므로 'a'를 기준으로 빼면 0~25 범위의 정수 인덱스를 얻을 수 있다.
char c = 'c';
cout << c - 'a'; // 결과: 2 ('c' - 'a' = 99 - 97)
- 코드에서 활용
cnt[s[i] - 'a']++; // 알파벳을 0~25 범위의 인덱스로 변환하여 개수 증가
// 범위 기반 for문 이용 (for(int i : cnt))
- C++11 이상에서 추가된 문법으로, `std::vector` 또는 배열을 순회할 때 유용하다.
- 기존의 for 루프에서 인덱스를 활용하는 방식보다 가독성이 좋고 코드가 간결하다.
// 기존의 인덱스 기반 for문
for (int i = 0; i < 26; i++) {
cout << cnt[i] << " ";
}
// 범위 기반 for문 (더 간결하다)
for (int i : cnt) {
cout << i << " ";
}
- 코드에서 활용
for (int i : cnt) cout << i << " ";
AI 피드백
#include <iostream>
#include <string>
using namespace std;
constexpr int ALPHA = 26; // 알파벳 갯수
/*
constexpr : 컴파일 타임 상수를 정의하는 키워드
- constexpr을 사용하면 반드시 컴파일 시점에 값이 결정됨
- const는 런타임에도 값이 결정될 수 있지만, constexpr은 무조건 컴파일 타임에 결정되어야 한다
*/
int cnt[ALPHA] = {0}; // 각 알파벳 개수를 저장할 배열 (초기값 0)
int main()
{
string s;
// 문자열을 입력한다
cin >> s;
// 문자열의 각 문자를 순회하며 알파벳 개수를 센다
// - string은 char로 구성되어 있다.
// - 이를 범위 기반 for문에 활용하여 각 알파벳 소문자의 갯수를 센다
// - 아스키코드 값을 이용해 cnt 배열의 해당 알파벳 위치에 접근하여 개수를 증가시킨다
for(char c : s) cnt[c - 'a']++;
// 각 알파벳의 개수를 출력한다
// - 삼항 연산자를 활용하여 마지막 값 뒤에는 개행, 나머지는 공백을 출력한다
for(int i = 0; i < ALPHA; i++)
cout << cnt[i] << (i == ALPHA - 1 ? "\n" : " ");
return 0;
}
사용한 핵심 개념
// `constexpr`을 활용한 컴파일 타임 상수 정의
- `constexpr` 키워드를 사용하여 컴파일 타임에 결정되는 상수를 정의하는 방식이다.
- `const`는 런타임에도 값이 결정될 수 있지만, `constexpr`은 반드시 컴파일 시점에 값이 확정되어야 한다.
- 매직 넘버(하드코딩된 숫자)를 없애고 의미를 명확하게 표현할 수 있다.
- 코드에서 활용
constexpr int ALPHA = 26; // 알파벳 개수 (a~z는 총 26개다)
- 기존 코드와의 차이점
// 기존 코드에서는 'z' - 'a' + 1로 배열 크기를 정의했지만,
// ALPHA라는 상수를 사용하면 더 직관적이고 유지보수가 편리하다.
int cnt[ALPHA] = {0};
// range-based for loop (범위 기반 for문) 활용
- `for (char c : s)`와 같은 구문을 사용하여, 문자열의 각 문자를 직접 순회하는 방식이다.
- 기존의 인덱스 기반 for 루프보다 더 직관적이고 간결하며, 가독성이 뛰어나다.
- 코드에서 활용
for (char c : s) cnt[c - 'a']++; // 문자를 직접 순회하며 카운트한다.
- 기존 코드와의 차이점
// 기존 코드
for (int i = 0; i < s.size(); i++)
cnt[s[i] - 'a']++;
// 개선된 코드 (더 간결해졌다.)
for (char c : s) cnt[c - 'a']++;
// 삼항 연산자 활용하여 출력 최적화
- 마지막 원소 출력 시 불필요한 공백을 방지하기 위해 삼항 연산자(?:)를 사용한 방식이다.
- if-else 문을 사용하는 것보다 더 간결하고 깔끔한 코드가 된다.
- 코드에서 활용
for (int i = 0; i < ALPHA; i++)
cout << cnt[i] << (i == ALPHA - 1 ? "\n" : " ");
- 기존 코드와의 차이점
// 기존 코드에서는 모든 출력값 뒤에 공백이 들어갔다.
for (int i : cnt) cout << i << " ";
// 개선된 코드에서는 마지막 값 뒤에 개행(\n)을 넣고, 나머지는 공백을 출력한다.
for (int i = 0; i < ALPHA; i++)
cout << cnt[i] << (i == ALPHA - 1 ? "\n" : " ");