프로그래밍 언어/C

C언어 백준 10809 번

happy_life 2021. 9. 4. 11:12

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

 

10809번: 알파벳 찾기

각각의 알파벳에 대해서, a가 처음 등장하는 위치, b가 처음 등장하는 위치, ... z가 처음 등장하는 위치를 공백으로 구분해서 출력한다. 만약, 어떤 알파벳이 단어에 포함되어 있지 않다면 -1을 출

www.acmicpc.net

 

문제

알파벳 소문자로만 이루어진 단어 S가 주어진다. 각각의 알파벳에 대해서, 단어에 포함되어 있는 경우에는 처음 등장하는 위치를, 포함되어 있지 않은 경우에는 -1을 출력하는 프로그램을 작성하시오.

 

 

 

 

풀이

 

 

 

틀린풀이

#include <stdio.h>

int main() {

	//단어의 길이 <=100
	//알파벳 소문자
	// 출력은 공백을 구분해서 한다.


	//1) 입력되는 단어는 문자열 배열 사용

	char Word[100]; //문자열 배열 선언
	printf("단어를 입력하시오\n");
	scanf("%s", Word); //문자열 형식은 &부호를 사용하지 않음
	
	//2) 알파벳 배열 추가 ( 출력이 숫자이므로 int 형)
	int  Alphabet[26]; //알파벳 총 26개 
	int k; //global 설정 for for 문을 위해
	for (int j = 0; j < sizeof(Alphabet) / sizeof(int); j++) {
		Alphabet[j] = -1;
	}
	

	

	//문자열 첫번째 부터 백번쨰 까지 
	for (k = 0; k < 100; k++) {
		

		//문자열 N번쨰 일떄 알파벳이 있는지 체크 및 Alphabet에 값 순서까지 넣어주기
		for (int z = 0; z < 26; z++) {

			
			if (Word[k] == 97 + z) {
				Alphabet[z] = k;
				
			}
			

		}
	}
	
		


	//배열 확인용 
	for (int i = 0; i < sizeof(Alphabet)/sizeof(int); i++) {

		printf("%d ", Alphabet[i]);

	}
	
	//3)순서 비교하기 및 출력 


	return 0;
}

이렇게 차이가 나는데 그 이유는 중복이 되면 그 코드가 그 다음에서 덮어써지기 때문이다.

(위의 예시에선 5->6 ) 

o가 2개이기때문에 6번째 자리일때 한번 들어간 것이 7번째 자리일 때 또 들어가게 되기 때문.

이 중복은 for 문이 문자열을 기준으로 돌기때문 (for k=0; k<100;k++)

이 구조로는 도저히 중복을 해결해줄 코드를 생각해내기 어려웠다. 

중복을 해결해줄 수 있는 다른 코드를 짜야했음. 

 

1)for 문을 알파벳 자리를 기준으로 돌려주는 idea(기준의 변경)

 

for (int i = 97; i <= 122; i++)

 

ASCII 코드 기준 a = 97 z = 122 이므로 

a부터 시작해 z까지를 계산하는 식

이것은 아까전의 식과 달리 a b c d e 순서대로 

판단하고 다음으로 넘어가므로 입력값에 있어서

중복이 발생하지 않는다.

for 문 안에서

ex) -1 -1 0 -1 이  

-1 -1 1 -1 로 바뀔 가능성이 없다는 것이다.

 

정답

#include <stdio.h>
#include <string.h> //strlen 함수를 위한 것 

int main() {

	char  Word[100];//문자열 배열 선언
	scanf("%s", Word);


	//a -> b -> c -> d 자리 수를 기준으로 for 문을 돌린다. 
	for (int i = 97; i <= 122; i++) {

		int cnt = 0; //위치 세주기를 위한 cnt 
		//NULL 나오기 전까지만 
		while (Word[cnt] != 0) {

			//조건:  문자열을 앞에서부터 체크하면서 같은 것을 만나면 break 해줌 
			if (Word[cnt] == i) {
				break;
			}
			cnt++;
			
		}

		if (Word[cnt] == i) {
			printf("%d ", cnt);
		}
		else
			printf("-1 ");

	}
	return 0;

}

 

Alphabet 배열을 굳이 만들지 않고, 순서대로 조건에 맞게 출력하는 방식을 선택하였다.

if (Word[cnt] == i) {
			printf("%d ", cnt);
		}
		else
			printf("-1 ");

 

 

 

기억해야할 포인트

1)코드는 최대한 짧게( 안쓸 수 있는 건 쓰지 않는 쪽으로)


2) 기준을 뭘로 잡느냐에 따라 코드가 완전 달라짐 (Alphabet 기준으로 for문을 돌릴지, 문자열 기준으로 for문을 돌릴지)


 3) 일단  기준 정해놓고 -> 예외 처리 

-예외까지 모두 고려해서 코드짜려고하면 머리가 해결 못함.

A기준을 만들어놓고 거기에 예외처리를 할 수 있게 조건을 추가하자.

 

4)코딩은 무조건 있다 없다를 기준으로 분류하는 것.(이산수학개념)

 

5) 문자열의 인수들을 %d 로 숫자로 출력하고 그걸 ASCII 코드를 활용하는 idea도 있음 (문자-숫자전환)

 

6)공통점을 최대한 활용하자

97~122를 차례대로 띄어 출력하면 굳이 알파벳 배열을 쓰지 않아도 된다.