-링크
https://school.programmers.co.kr/learn/courses/30/lessons/120838?language=c
-문제 설명
머쓱이는 친구에게 모스부호를 이용한 편지를 받았습니다. 그냥은 읽을 수 없어 이를 해독하는 프로그램을 만들려고 합니다. 문자열 letter가 매개변수로 주어질 때, letter를 영어 소문자로 바꾼 문자열을 return 하도록 solution 함수를 완성해보세요.
모스부호는 다음과 같습니다.
morse = {
'.-':'a','-...':'b','-.-.':'c','-..':'d','.':'e','..-.':'f',
'--.':'g','....':'h','..':'i','.---':'j','-.-':'k','.-..':'l',
'--':'m','-.':'n','---':'o','.--.':'p','--.-':'q','.-.':'r',
'...':'s','-':'t','..-':'u','...-':'v','.--':'w','-..-':'x',
'-.--':'y','--..':'z'
}
-제한사항
- 1 ≤ letter의 길이 ≤ 1,000
- return값은 소문자입니다.
- letter의 모스부호는 공백으로 나누어져 있습니다.
- letter에 공백은 연속으로 두 개 이상 존재하지 않습니다.
- 해독할 수 없는 편지는 주어지지 않습니다.
- 편지의 시작과 끝에는 공백이 없습니다.
- a ~ z에 해당하는 모스부호가 순서대로 담긴 배열입니다.
- {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."}
-입출력 예
".... . .-.. .-.. ---" | "hello" |
".--. -.-- - .... --- -." | "python" |
-해설 (Java)
이 문제를 HashMap을 이용해서 풀이할 수 있겠지만, 나의 경우 Array를 사용해서 풀이하였다. HashMap의 경우 모스부호를 Key값으로, 알파벳을 value값으로 넣어 빠르게 찾을 수 있겠지만 모스부호를 일일히 26번(알파벳의 개수) put하는 점에서 풀이하는 속도와 귀찮은(?)점을 고려하여 String 배열로 풀이하는 것이 더 이점이 있다고 생각하였다.
그래서 morseArray 배열에 모스부호를 넣어 배열을 구성하고, 그 이후 split함수를 사용하여 공백으로 문자열을 잘라 String 배열로 받아주었다.
공백으로 잘려 문자열 배열으로 구성 된 값을 morseArray에서 찾아 배열의 인덱스를 구하고, 인덱스 값과 a의 (Ascii)값을 더한 후 아스키코드를 문자열로 casting하고 문자를 문자열로 변환하여 answer에 이어 주어 답을 도출 해 내었다.
C언어와는 달리 메모리를 할당하고, 문자열을 자르고 하는 과정이 없어도 되므로 코드의 길이를 간결하게 작성할 수 있었다.
-Java풀이
import java.util.Arrays;
class Solution {
String [] morseArray = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
public String solution(String letter) {
String [] mos;
String answer = "";
char temp;
mos = letter.split(" ");
for(String i : mos){
answer += String.valueOf((char)(Arrays.asList(morseArray).indexOf(i)+'a'));
}
return answer;
}
}
-해설 (C)
모스부호가 배열로 주어지기 때문에 전역변수에 모스부호를 배열로 선언 해 놓았다.
우선 문자열 letter로 들어오는 모스부호는 한 알파벳씩 공백으로 분리하여 들어오기 때문에, anwer로 return 할 때 answer의 크기 즉 문자의 개수는 공백의 개수 +1개이다.
그래서 anwer을 malloc할 때 공백의 개수를 구하고, 그 공백의 개수에서 +1개와 문자열 null문자를 포함할 1자리수 즉 공백의 개수 + 2개로 할당 해 주었다.
공백의 개수는 find_blank수를 만들어 문자열의 공백을 찾아 공백의 개수를 return 하도록 하였다.
이 부분은 실제 시험에서 for문을 돌려 공백의 개수를 구하는 것 보단 제약사항을 보고 최대 길이값으로 할당하는 것이 더 괜찮을 것 같다.
모스부호에 해당하는 알파벳을 찾을 땐 공백으로 문자열을 잘라 알파벳을 찾도록 하였는데, 들어오는 문자열 값이 const 이기 때문에,
문자열을 복사해서 사용해주었다. 실제로 strtok를 사용할 때 문자열 원본이 변형될 수 있기 때문에 원본을 보존해야하는 경우 복사해서 사용해야 한다.
또한 스레드 안에서 사용 할 경우 스레드세이프를 위해 strtok 대신 strtok_r를 사용하는 것이 좋다.
strtok을 while문안에 넣어 토큰을 잘라 나오는 문자열 포인터 값이 null이 아닐 때 까지 alphabet을 전역변수에 선언 해 두었던 모스부호 배열과 비교를 하였는데, 그 함수가 find_alphabet이다. 문자열의 번호 순서대로 abc...이기 때문에 return할 때는 char로 return 할 수 있도록 구성하였고, return할때 바로 char값을 받을 수 있도록 i+'a'를 retrun하였고 이 부분은 아스키 코드를 활용하여 도출한 값이다.
비교적 길고 복잡해 보이지만 들어오는 문자열이 공백으로 띄워져있기 때문에 쉽게 답을 도출해낼 수 있다.
-C풀이
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
char MORSE_CODE[26][5] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
int find_balnk(char *str){
int cnt = 0;
for(int i = 0; i < strlen(str); i++){
if(str[i] == ' ')
cnt++;
}
return cnt;
}
char find_alphabet(char *str){
int i = 0;
for(i = 0; i < 26; i++){
if(strcasecmp(&MORSE_CODE[i],str) == 0)
break;
}
return i+'a';
}
// 파라미터로 주어지는 문자열은 const로 주어집니다. 변경하려면 문자열을 복사해서 사용하세요.
char* solution(const char* letter) {
// return 값은 malloc 등 동적 할당을 사용해주세요. 할당 길이는 상황에 맞게 변경해주세요.
char* answer = NULL;
char * letter_ = NULL;
char *temp = NULL;
int cnt = 0, i = 0;
letter_ = (char*)malloc(sizeof(char)*strlen(letter)+1);
memset(letter_,0x00,sizeof(char)*strlen(letter)+1);
strcpy(letter_,letter);
cnt = find_balnk(letter);
answer = (char*)malloc(sizeof(char)*cnt+2);
memset(answer,0x00,sizeof(char)*cnt+2);
temp = strtok(letter_," ");
answer[i]=find_alphabet(temp);
i++;
while(temp != NULL){
temp = strtok(NULL," ");
if(temp != NULL)
answer[i]=find_alphabet(temp);
i++;
}
return answer;
}
'Algorithm > Programmers' 카테고리의 다른 글
[프로그래머스] 코딩테스트 연습 - 큰 수 만들기 (Java, C) (1) | 2022.12.03 |
---|---|
[프로그래머스] 코딩테스트 연습 - 올바른 괄호 (Java, C) (0) | 2022.12.01 |
[프로그래머스] 코딩테스트 연습 - 기사단원의 무기 (Java, C) (0) | 2022.11.29 |
[프로그래머스] 코딩테스트 연습 - 과일장수 (Java, C) (0) | 2022.11.27 |
[프로그래머스] 코딩테스트 연습 - 명예의 전당(1) (Java, C) (0) | 2022.11.27 |