BAEKJOON

[백준] 1157 - 단어 공부

멍정 2022. 11. 24. 21:20

어제부터 했는데 암만해도 실패로 뜨더라구요

알고리즘 자체에 문제가 있는건가 싶어서 다른 분들 글도 읽어봤는데

앞구르기 하면서 봐도 같은 방식이라서! 왜 실패하는지 이해가 안가길래

백준 질문 게시판을 이용해봤습니다.

 

그리고 받은 대답

아 세상에. 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