어제부터 했는데 암만해도 실패로 뜨더라구요
알고리즘 자체에 문제가 있는건가 싶어서 다른 분들 글도 읽어봤는데
앞구르기 하면서 봐도 같은 방식이라서! 왜 실패하는지 이해가 안가길래
백준 질문 게시판을 이용해봤습니다.
그리고 받은 대답
아 세상에. char로 선언해서 어마무시하게 큰 값을 처리를 못하는거였습니다.
앞으로는 변수의 크기도 잘 고려하면서 풀 수 있겠죠?
천천히 봐봅시당
우선 전체적인 흐름은?
1. 알파벳 갯수 만큼의 배열을 생성한다.
2. 입력받은 값을 앞에서 생성한 배열에 갯수를 넣어준다.
3. 가장 큰 값이 중복되는지 확인한다.
요런 흐름입니당.
#include<stdio.h>
#include<string.h>
int main (void)
{
char string[1000000];
int alphabet[26] = {};
int differenceValue = 'a' - 'A';
scanf("%s", string);
int i = 0;
while (string[i])
{
if(string[i] >= 'a'){
string[i] -= differenceValue;
}
alphabet[string[i] - 'A']++;
i++;
}
int mostUse = 0;
for(int t = 1; t < 26; t++){
if(alphabet[mostUse] < alphabet[t])
mostUse = t;
}
int checkpoint = 0;
for(int q = 0; q < 26; q++)
if(alphabet[q] == alphabet[mostUse])
checkpoint++;
if (checkpoint > 1)
printf("?");
else{
printf("%c", mostUse + 'A');
}
}
step1
대문자와 소문자를 구분하지 않고 카운트 하기 때문에 if문으로 소문자는 대문자로 변형한 후 배열에 넣어줬어요
int differenceValue = 'a' - 'A';
int i = 0;
while (string[i])
{
if(string[i] >= 'a'){
string[i] -= differenceValue; //소문자를 대문자로 바꿔주기
}
alphabet[string[i] - 'A']++;
i++;
}
사실 요걸 이해하려면 아스키코드를 먼저 알아야합니당
ASCII (American Standard Code for Information Interchange, 미국 정보 교환 표준 부호)
아스키 코드는 1963년 미국 ANSI에서 표준화한 정보교환용 7비트 부호체계이다. 인쇄전신기(Teleprinter)[2]를 통한 전신(통신)에서 사용되기 시작했고, 8비트 컴퓨터에서도 활용되어 오늘날 문자 인코딩의 근간을 이루게 된다.
표를 보고 간단하게 이해하자면 A는 65, a는 97이기 때문에
differenceValue = 'a' - 'A' (97-65)를 해주면 모든 소문자에서 differenceValue를 뺀 값이 대문자가 되게 됩니당
물론 이건 자동형변환도 되었기 때문이겠죠?
(아니면.. 조용히 글 고치러 와용)
사실 처음에 for문으로 돌렸는데 자꾸 시간초과가 뜨길래 바꿔줬습니당
그리고 alphabet 배열에 값을 증가시켜줬습니당
b를 입력하면
'b' -> 'B' -> alphabet['B' - 'A']++ 의 흐름으로 작동하면서 결과적으로 alphabet[1]의 값이 1 증가하게 됩니당.
step2
알파벳의 갯수를 다 저장했으면 가장 많이 사용된 값이 무엇인지 알아야겠죠!
배열에서 가장 큰 값이 무엇인지 찾아주면 됩니다.
int mostUse = 0;
for(int t = 1; t < 26; t++){
if(alphabet[mostUse] < alphabet[t])
mostUse = t;
}
step3
가장 큰 값을 출력하는거면 이대로 출력해도 괜찮겠지만!
단, 가장많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다
요런 경우가 있으니까 반복문을 사용해서 다시 한 번 확인해줬습니다.
alphabet[mostUse]의 값이 가장 클테니 해당하는 값이 1개보다 많으면 여러 개 존재한다고 생각할 수 있겠죵!
(하나는 자기 자신일테니까용)
int checkpoint = 0;
for(int q = 0; q < 26; q++)
if(alphabet[q] == alphabet[mostUse])
checkpoint++;
if (checkpoint > 1)
printf("?");
else
printf("%c", mostUse + 'A');
만약 alphabet[mostUse]의 값과 같은 값이 있으면 checkpoint의 값을 증가시켜주고
만약 checkpoint의 값이 1보다 크다면 ?를 출력해줬어요
문제를 마주하면 직접 풀어보려고 하는 편인데
이번에는 그 어떤 입력값을 넣어도 원하는 결과가 출력되고
(과정을 출력했을 때도 원하는 값이 나왔음 ㅠㅠ)
이유를 알 수 없는 실패만 와장창 떠서 찾아봤는데
아직 배우는 입장이니까 찾아보면서 배워도 괜찮지 않나.. 싶네용
백준 질문 게시판도 아주 좋았어요.. 댓글 주신분 아니었으면 아직도 노트북을 잡고 화내고 있었을텐데..
모르면! 찾아보는 것도 좋은 공부가 될 것 같아요!

'BAEKJOON' 카테고리의 다른 글
[백준] 2675 - 문자열 반복 (1) | 2022.11.22 |
---|---|
[백준] 10809 - 알파벳 찾기 (0) | 2022.11.21 |
[백준] 4673 - 셀프 넘버 (0) | 2022.09.18 |