알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.
첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.
첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.
보면 브론즈1문제인데도 상당한 정답비율을 보여준다.
필자또한 코딩을 처음시작한 2년전에.. 상당한 시도끝에 틀린문제로 남아있었다..
다시 문제를 보고 판단한결과, 입력값은 100만크기의 문자열이고,
시간은 2초, 메모리또한 넉넉히 줬는데
C++의 scanf는 string으로 값을 못받기때문에(가능은하다고는한다) char[]로 받고, (이 배열의 최대크기는 100만으로 고정)
앞부터 탐색하여 각각의 알파벳 소문자, 대문자를 int배열인 alphabet[0~25]++ 하면 될것같았다.
아직도 가장애먹는게 char를 int로 바꿀때 아스키코드값을 참고하는것인데 두가지를 기억하면된다.
- char - 숫자 => 숫자 (char - 숫자인 아스키코드값)
char - 'char2' => 숫자 (char, char2 아스키코드값차)- (char)(char - 'char') => 결과인아스키코드값을 문자로
(char)(char - '숫자) => 결과인아스키코드값을 문자로
즉, 기본적으로 아스키코드값을 기준으로 계산하되, 숫자그대로냐, 문자를 아스키코드값으로 바꾸어 계산하냐 이며,
형변환을 안할시 아스키코드값인 정수값이 출력되는것
따라서 char형 변수에 바로 담아 쓸 수 있다. (자동형변환지원)
이제 마지막으로 출력값이 가장 빈도수가높은 문자를 대문자로 출력하되, 최빈도 문자가 두개이상이면 ? 을 출력하도록한다.
여기서 3가지변수를 작성하면된다.
alphabet배열로 카운트된 문자를 비교할때
최대빈도수를 담을 max, 이때의 인덱스인 maxIndex (결국 대문자를 출력해야하므로), 중복되는지 확인할 bool overlap
최댓값을 갱신할때 overlap을 false로 초기화하며 인덱스도 기록하고,
갱신된 최댓값과 현재 알파벳의 빈도수가 같을경우 overlap을 true로설정.
이제 출력은
간단하게 작성할 수 있다.
뿌듯
#define _CRT_SECURE_NO_WARNINGS //scanf오류 없앰
#include <bits/stdc++.h>
using namespace std;
int main(void) {
char input[1000000]; // scanf는 string으로못받음 char[]로 받는다.
int alphabet[26] = {0}; //0~25 : A~Z
scanf("%s", &input);
for (int i = 0, index; i < 1000000; i++) {
if (input[i] == NULL) break;
if (97 <= input[i] && input[i] <= 122) { //소문자
index = input[i] - 97;
}
else { //대문자
index = input[i] - 65;
}
alphabet[index]++;
}
int max = 0;
int maxIndex = 0;
bool overlap = false;
for (int i = 0; i < 26; i++) {
if (alphabet[i] > max) {
max = alphabet[i];
maxIndex = i;
overlap = false;
}
else if (alphabet[i] == max) {
overlap = true;
}
}
if (overlap) {
printf("?");
}
else {
printf("%c", (char)('A' + maxIndex));
}
}