Excercism - Squeaky Clean : 문자열, 아스키코드, 이모지, 숫자 구분 등
문제요약
문자가 주어지면, 특정 규칙을 적용해 다듬어라!
https://exercism.org/tracks/csharp/exercises/squeaky-clean
Squeaky Clean in C# on Exercism
Can you solve Squeaky Clean in C#? Improve your C# skills with support from our world-class team of mentors.
exercism.org
난이도
Learning Excercise
풀이 포인트
- 그리스 문자 판별
// char 형은 16비트 정수형이다. 대소 비교로 그리스어 범위 한정할 수 있다.
c >= 'α' && c <= 'ω'
- 이모지 판별
// IsLetter: 유니코드 문자 범주에 포함되는지 판단.
// 정확하게는 모르겠으나 이걸로 이모지는 탈락시킬 수 있었다.
char.IsLetter(a);
- 케밥케이스 → 카멜케이스 변경
// 케밥 케이스
do-re-mi-fa-sol
// 카멜 케이스
doReMiFaSol
- StringBuilder 활용
https://machineboy0.tistory.com/341
C# 문자 형식 char, 문자열 형식 string, String Builder
Char 형char 형식은 Integer Type(정수 형식)에 속한다.하지만 수가 아닌 '가', '나',' 다', 'a', 'b', 'c' 와 같은 문자 데이터를 다룬다.2 byte(16 bit)크기로, 텍스트의 가장 작은 요소를 나타낸다.UTF-16 Unicode를
machineboy0.tistory.com
REVIEW
이모지 판별과 그리스어 판별을 어떻게 하는지 구글링을 하는데 시간이 많이 걸렸다.
결국 모범 답안을 참고했는데 IsLetter()로 분간되는 유니코드 문자 범위엔 이모지가 포함되지 않는듯 하다.
근데 또 검색해보면 이모지 또한 유니코드라고 하고 이건 좀 더 찾아봐야 한다.
그리고 늘 문자를 아스키코드로 변환한 뒤, 대소 비교나, 범위 한정에 사용해야 한다고 생각해버리는데,
풀어 말해, A는 96임을 알고 있어야 한다고 생각하는데 'A' char형으로 대소 비교 해버리면 된다는 것 잊지 말기..
그리고 케밥케이스라는 것은 처음 접했는데,
나는 Split 함수를 활용해 '-'기준으로 나눈뒤, 단어의 첫 글자를 대문자로 변환해 다시 연결하는 식으로 구현했지만,
모범 풀이를 보니 isAfterDash라는 flag값을 하나 두고 이를 껐다 키며 문자를 조합하더라.
머리 좋은 것 같다.
그리고 차차 Linq도 익숙해져 나가야 한다..
CODE
using System;
using System.Text;
public static class Identifier
{
// 그리스어 문자 판별 (대소문자 모두 포함)
public static bool IsGreekLetter(char c)
{
return (c >= 'α' && c <= 'ω');
}
public static string Clean(string identifier)
{
// 입력이 빈 문자열이면 바로 반환
if (string.IsNullOrEmpty(identifier)) return "";
StringBuilder sb = new StringBuilder();
foreach (char a in identifier)
{
if (a == ' ')
{
sb.Append('_'); // 공백 → '_'
}
else if (a == '\0')
{
sb.Append("CTRL"); // NULL 문자 → "CTRL"
}
else if (IsGreekLetter(a))
{
continue; // 그리스어 제거
}
else if (char.IsLetter(a) || a == '-')
{
sb.Append(a);
}
else
{
continue;
}
}
// '-'로 나눈 배열에서 빈 문자열 제외
string[] kebab = sb.ToString().Split('-');
// 첫 번째 단어는 그대로
string answer = kebab[0];
Console.WriteLine(sb.ToString());
Console.WriteLine(kebab[0]);
// 두 번째 단어부터 첫 글자 대문자로 변환
for (int i = 1; i < kebab.Length; i++)
{
char first = char.ToUpperInvariant(kebab[i][0]);
answer += first + kebab[i].Substring(1);
}
return answer;
}
}
using System.Text;
public static class Identifier
{
private static bool IsGreekLowercase(char c) => (c >= 'α' && c <= 'ω');
public static string Clean(string identifier)
{
var stringBuilder = new StringBuilder();
var isAfterDash = false;
foreach (var c in identifier)
{
stringBuilder.Append(c switch
{
_ when IsGreekLowercase(c) => default,
_ when isAfterDash => char.ToUpperInvariant(c),
_ when char.IsWhiteSpace(c) => '_',
_ when char.IsControl(c) => "CTRL",
_ when char.IsLetter(c) => c,
_ => default,
});
isAfterDash = c.Equals('-');
}
return stringBuilder.ToString();
}
}