프로그래밍 언어/C

C언어 백준 2941 크로아티아 알파벳 풀이과정

happy_life 2021. 9. 11. 16:34

https://www.acmicpc.net/problem/2941

 

2941번: 크로아티아 알파벳

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다. 크로아티아 알파벳 변경 č c= ć c- dž dz= đ d- lj lj nj nj š s= ž z=

www.acmicpc.net

문제

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수가 없었다. 따라서, 다음과 같이 크로아티아 알파벳을 변경해서 입력했다.

크로아티아 알파벳변경

크로아티아 알파벳

예를 들어, ljes=njak은 크로아티아 알파벳 6개(lj, e, š, nj, a, k)로 이루어져 있다. 단어가 주어졌을 때, 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.

dž는 무조건 하나의 알파벳으로 쓰이고, d와 ž가 분리된 것으로 보지 않는다. lj와 nj도 마찬가지이다. 위 목록에 없는 알파벳은 한 글자씩 센다.

풀이

 

출제포인트 분석

 

1)dž는 무조건 하나의 알파벳으로 쓰이고, d와 ž가 분리된 것으로 보지 않는다.

 

->변경되는 문자열 덩어리를 하나로 만들어라.

 

2)ddz=z= 의 출력 값이 3이다. 따라서 같은 d로 시작하지만, 'd'와 'dz=' 는 다르다.

 

->같은 문자로 시작하지만, 다른 문자를 구분하는 문제를 해결해라.

 

 

 

 

idea

1)예제 입력 (4) c=c= 의 출력값이 2이다. 따라서 중복을 고려하지 않는다.

 

 

2)기본적인 알파벳은 그냥 count하고(원칙)

  예제로 주어진 문자열의 앞 자리 문자 (예를 들어 'c='이면 c)를 기준으로 문자열을 구분한다.(예외)

 

3)덩어리 이므로 if 문을 두 번사용하여 조건이 맞는 경우 count를 해주고, 그 다음 인덱스로 넘어가기 위해 i++를 해준다.

 

4)같은 문자로 시작하지만, 다른 문자를 어떻게 구별할까? 앞자리 c,d,l,n,s,z 일 때와 아닐 때를 나눠서 조건에 따라 정리

풀이과정

 

1)문자열  입력

	//1)문자열  입력

	scanf("%s", input); // ljes=njak
	printf("%s", input); // ljes=njak

 

 

 

2)알파벳 변환

 

 

for (int i = 0; input[i] != '\0'; i++)//i=9에서 종료
	{
		if(input[i] == 'c')
		{
			if (input[i + 1] == '=' || input[i+1] == '-')
			{
				i++;
				count++;
				
				continue;
			}

			count++;
		}
        
		else
		{
			count++;
			printf("--------else count-------\n");
		}

 

 

Q)if (input[i + 1] == '=' || input[i+1] == '-') 이런식으로 한번에 경우를 따져도될까?

어차피 'c='나'c-'는 하나로 count 되는 것이므로, 개수의 입장에선 동일한 case이다.

c=이 3개 ==가 2개 c-가 2개 총 7개

 

 

3) d의 경우 케이스 분리하기('dz=' 와 'd-')

 


		}
		//3)d의 경우 case분류하기
		if (input[i] == 'd')
		{
			if (input[i + 1] == '-')
			{
				i++;
				count++;
				continue;
			}

			if (input[i + 1] == 'z')
			{
				if (input[i + 2] == '=')
				{
					i=i+2;//인덱스 두 칸 넘어가야 하므로
					count++;
					continue;
				}

				else 
				{
					
					count++;
					continue;

				}
			}
		}

Q) i = i+2 는 왜 작성한 것인가?

i=i+2;//인덱스 두 칸 넘어가야 하므로

idea 3)의 활용임.

 

Q)else 부분은 왜 i++가 없을까?

예를 들어 'dz='가 아닌 'd'z'd'에서의 dz는 문자열 덩어리가 아닌 평범한 알파벳이기때문에 index를 건너뛰는 것이 아니라 index가 그대로 넘어가야하기 때문

 

 

답안 해설 코드

#include <stdio.h>
#include <string.h>

int main()
{
	char input[101]; //100까지니까 char 배열 크기 100+1 = 101
	int count = 0; // 알파벳의 개수 

	//1)문자열  입력

	scanf("%s", input); // ljes=njak

	//2)알파벳 변환

	for (int i = 0; input[i] != '\0'; i++)//i=9에서 종료
	{
		if(input[i] == 'c')
		{
			if (input[i + 1] == '=' || input[i+1] == '-')
			{
				i++;
				count++;
				continue;
			}
		}

		//3)d의 경우 case분류하기
		if (input[i] == 'd')
		{
			if (input[i + 1] == '-')
			{
				i++;
				count++;
				continue;
			}

			if (input[i + 1] == 'z')
			{
				if (input[i + 2] == '=')
				{
					i=i+2;//인덱스 두 칸 넘어가야 하므로
					count++;
					continue;
				}

				else 
				{
					
					count++;
					continue;

				}
			}
		}
		
		if (input[i] == 'l')
		{
			if (input[i + 1] == 'j')
			{
				i++;
				count++;
				continue;
				
			}
		}
		
		if (input[i] == 'n')
		{
			if (input[i + 1] == 'j')
			{
				i++;
				count++;
				continue;
			}
		}
		
		if (input[i] == 's')
		{
			if (input[i + 1] == '=')
			{
				i++;
				count++;
				continue;
			}	
		}

		if (input[i] == 'z')
		{
			if (input[i + 1] == '=')
			{
				i++;
				count++;
				continue;
			}
			count++;
		}

		else
		{
			count++;
		}
	}
	//4) 더해서 출력 
	printf("%d",count);;
	return 0;
}

Q) z관련 if문의 else 에만 count++;가 있는 이유? 

else는 바로 앞의 if를 기준으로 한다. 따라서 else의 범위는 z가 아닐 때

z만 입력됐을 경우를 생각해보자.