본문 바로가기
온라인 저지/BOJ

[BOJ/C]1157 단어 공부

by ahj 2021. 9. 25.

대형(?) 문자열을 입력하는거는 항상 너무 어렵다..

코딩 문제를 풀 때마다 나를 괴롭히는 segment fault 런타임 에러... 논리를 알면 뭐하나 데이터 처리를 잘 못하는데 데이터 공부를 해야겠다.

#include <stdio.h>

int main()
{
  char s[1000010], alphabet[30];
  int a[30]={0,}, cnt=0, max_index;//array들은 넉넉하게 30칸씩
  for(int i=0;i<26;i++)
  {
    alphabet[i]='a'+i;//alphabet array에 a~z까지 저장하기
  }
  scanf("%s", s);//s array애 문자열 저장
  for(int i=0;i<sizeof(s);i++)//이러면 최대 1000000번 반복
  {
    if(s[i]=='\0') break;//입력값이 NULL일때 처리
    else if(s[i]>=65&&s[i]<=90) s[i]=s[i]+32;//C++은 lowercase 함수가 따로 없기 때문에 구현해줘야 한다. ASCII코드에 따라 대문자 문자 사이일 때 32씩 더해줘서 소문자화
    for(int j=0;j<26;j++)//입력된 character와 alphabet array 각 item과 비교하기 위해 for문 구현
    {
      if(s[i]==alphabet[j]) a[j]+=1;//a array는 각 알파벳 위치 카운트를 반환하기 위해 임의로 선언한 정렬, 입력된 값과 alphabet item과 같을 때 +1
    }
  }
  int max = a[0];
  for(int i=1;i<26;i++)
  {
    if(a[i]==max) cnt=1;//max값이 겹칠 경우 cnt=1로 저장
    else if(a[i]>max)//각 알파벳 카운트 중 가장 큰 위치를 max값에 저장
    {
      max=a[i];
      cnt=0;//max값이 하나일 경우를 반환해주기 위한 선언
      max_index=i;//max값의 주소 반환
    }
  }
  if(cnt==1) printf("?");//max가 2개 이상이면 ? 출력
  else 
  {
    printf("%c", alphabet[max_index]-32);//대문자화 해서 출력
  }

  return 0;
}

틀린 코드. 

  • 런타임 에러 : 프로그램이 비정상적으로 종료한 경우입니다. Exit code가 0이 아닌 경우, segmentation fault를 받은 경우가 대표적입니다.

백준 오류 설명에 따르면 다음과 같다. 다시보니 정답률 40% 밖에 안되는 꽤나 까다로운 문제였던 것 같은데 아무래도 데이터 처리 때문인것 같다. 왜 segfault 났을까 계속 검색하고 고민하고 분석했지만 이유를 잘 모르겠다.

exit 코드도 올바르고

#include <stdio.h>

int main()
{
  char s[1000001];
  int a[30]={0,}, cnt=0, max_index, max=0;
  scanf("%s", s);
  for(int i=0;s[i]!='\0';i++)//break할 부분도 if문 처리하는 것보단 for문 안에서 처리했다.
  {
    if(s[i]>='a')
      s[i]=s[i]-32;//어차피 출력을 대문자로 해줄꺼면 대문자화하는게 더 편할 것이다.
    a[s[i]-'A']++;//내가 했던 방법과 다르게 알파벳의 ascii 10진수를 바로 이용해주면 됐다. 괜히 바보 같이 알파벳 array를 만들어줘갖고..
  }
  for(int i=0;i<26;i++)
  {
    if(a[i]==max)
      cnt=1;
    else if(a[i]>max)
    {
      max=a[i];
      cnt=0;
      max_index=i;
    }
  }
  if(cnt==1) 
    printf("?\n");
  else 
    printf("%c", max_index+65);//max_index가 ascii주소로 따지면 0부터 26사이의 숫자가 나올테니 문자로 반환해주기 위해 65(A)를 더한다.

  return 0;
}

문자열 선언에서 오류가 있는 줄 알고 30분을 검색하면서 헤매다가 같은 백준 문제 풀이까지 있어서 봐서 참고해서 정답을 짜봤다.

 

내가 했던 방법과 다르게 알파벳의 ascii 10진수를 바로 이용해주면 됐다. 괜히 바보 같이 알파벳 array를 만들어줘갖고.. 정답을 짜보고 생각을 해보니 아마도 character array를 건드리는 과정에서 NULL값을 건드리게 되었나보다.

 

 

오늘의 교훈

- 문자열을 다룰 때 ASCII코드를 잘 활용하자

댓글