Computer/Coding Test
Pangram, Isogram, Anagram, Acronym - 문자열 다루기, Linq
안녕도라
2025. 2. 7. 17:01
1️⃣ Pangram
더보기
모든 문자를 적어도 한 번 이상 사용하여 만든 문장
예) The quick brown fox jumps over the lazy dog.
나의 풀이
- 주어진 입력 문자를 순회하며 알파벳 모두를 가지고 있는 배열의 요소와 비교하고, 같다면 지워 나간다.
- 모두 순회한 후, 알파벳 배열이 빈다면 true
using System;
using System.Collections.Generic;
// 대소문자 구분 없이, 26개의 알파벳을 다 사용한다.
public static class Pangram
{
public static bool IsPangram(string input)
{
List<char> alphabets = new List<char>{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','w','u','x','y','z'};
if(input.Length == 0) return false;
string lowerInput = input.ToLower();
foreach(char a in lowerInput)
{
if(alphabets.Contains(a)){
alphabets.Remove(a);
}
}
return alphabets.Count == 0;
}}
모범 풀이
- 모든 알파벳을 포함한 문자열을 순회하며 입력값이 이 값을 가지고 있는지 확인
- 하나라도 가지고 있지 않다면 false
using System.Linq;
public static class Pangram
{
private const string Letters = "abcdefghijklmnopqrstuvwxyz";
public static bool IsPangram(string input)
{
var lowerCaseInput = input.ToLower();
return Letters.All(letter => lowerCaseInput.Contains(letter));
}
}
Linq 문법 설명
2️⃣ Isogram
더보기
중복되는 문자가 없는 단어
예) lumberjacks
나의 풀이
- 중복을 허용하지 않는 자료구조인 HashSet을 사용하여, hashset에 넣기 전 문자열의 길이와 hashset의 길이를 비교하는 방식으로 판단
using System;
using System.Collections.Generic;
// Isogram : 반복 글자 없음. 공백, - 허용
public static class Isogram
{
public static bool IsIsogram(string word)
{
int spaceHypenCount = 0;
HashSet<char> words = new HashSet<char>();
string lowerWord = word.ToLower();
foreach(char a in lowerWord){
if(char.IsLetter(a)){
words.Add(a);
}else{
spaceHypenCount++;
}
}
return (word.Length - spaceHypenCount) == words.Count;
}
}
모범 풀이
- 중복 제거한 후의 길이와 처음 입력 문자 길이 비교 (아이디어는 동일)
using System.Linq;
public static class Isogram
{
public static bool IsIsogram(string word)
{
var lowerLetters = word.ToLower().Where(char.IsLetter).ToList();
return lowerLetters.Distinct().Count() == lowerLetters.Count;
}
}
Linq 문법 설명
3️⃣ Anagram
더보기
단어의 문자를 재배열하여 다른 뜻을 가지는 다른 단어로 바꾸는 것
예)
Murder → Redrum
Listen → Silent
나의 풀이
- 입력 문자와 비교 문자의 길이가 다르면 애초에 성립하지 않음
- 입력 문자와 비교 문자 모두 정렬하여 그것이 동일한지 비교.
using System;
using System.Collections.Generic;
public class Anagram
{
private string baseWord;
public Anagram(string baseWord)
{
this.baseWord = baseWord.ToLower(); // baseWord를 대소문자 구분 없이 저장
}
// 문자열을 알파벳 순으로 정렬하는 메서드
private string Sort(string word)
{
char[] characters = word.ToLower().ToCharArray(); // 대소문자 구분 없이 처리
Array.Sort(characters);
return new string(characters);
}
public string[] FindAnagrams(string[] potentialMatches)
{
List<string> answer = new List<string>();
foreach (string a in potentialMatches)
{
// 길이가 다르면 애초에 anagram이 아님
if (a.Length != this.baseWord.Length) continue;
// baseWord와 동일한 단어는 애너그램으로 간주하지 않음
if (a.ToLower() == this.baseWord) continue;
// 알파벳 순으로 정렬하여 비교
if (Sort(a) == Sort(this.baseWord))
{
answer.Add(a);
}
}
return answer.ToArray();
}
}
모범 풀이
- 아이디어 동일
using System;
using System.Collections.Generic;
using System.Linq;
public class Anagram
{
private readonly string _word;
public Anagram(string word) => _word = word;
public IEnumerable<string> FindAnagrams(IEnumerable<string> candidates) =>
candidates.Where(IsAnagram).ToArray();
private bool IsAnagram(string candidate) =>
SortedLowerCase(candidate) == SortedLowerCase(_word) && IsDifferentFromWord(candidate);
private bool IsDifferentFromWord(string candidate) =>
!string.Equals(candidate, _word, StringComparison.OrdinalIgnoreCase);
private static string SortedLowerCase(string word) =>
new(word.ToLower().Order().ToArray());
}
Linq 문법 설명
4️⃣ Acronym
더보기
머리글자를 모아 만든 준말
예)
As Soon As Possible → ASAP
Liquid-crystal display → LCD
Thank George It's Friday! → TGIF
나의 풀이
- 단어 사이의 구분자(공백, -, _)를 일일히 지정하여 그것을 기준으로 split한다.
- 첫 글자만 대문자로 바꾸어 더해준다.
using System;
public static class Acronym
{
public static string Abbreviate(string phrase)
{
if (string.IsNullOrEmpty(phrase)) return "";
// 공백이나, -로 나눈 다음 첫 글자를 대문자로
string[] splited = phrase.Split(new char[] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries);
string answer = "";
foreach (string word in splited)
{
answer += char.ToUpper(word[0]);
}
return answer;
}
}
모범 풀이
- 단어 사이의 구분자를 Regex 정규표현식으로 찾아내어 split한다.
- 첫번째 문자를 대문자화하여 배열화(string).
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public static class Acronym
{
public static string Abbreviate(string phrase) =>
new(phrase.Words().Select(FirstLetter).ToArray());
private static IEnumerable<string> Words(this string phrase) =>
Regex.Split(phrase, @"[^\w]+");
private static char FirstLetter(string word) =>
char.ToUpper(word[0]);
}
Linq 문법 설명
https://machineboy0.tistory.com/328