[문과 코린이의 IT 기록장] C# 프로그래머스(Programmers) - 둘만의 암호
[문과 코린이의 IT 기록장] C# 프로그래머스(Programmers) - 둘만의 암호
1. Problem
1) 문제 설명
두 문자열 s와 skip, 그리고 자연수 index가 주어질 때, 다음 규칙에 따라 문자열을 만들려 합니다. 암호의 규칙은 다음과 같습니다
- 문자열 s의 각 알파벳을 index만큼 뒤의 알파벳으로 바꿔줍니다.
- index만큼의 뒤의 알파벳이 z를 넘어갈 경우 다시 a로 돌아갑니다.
- skip에 있는 알파벳은 제외하고 건너뜁니다.
예를 들어 s = "aukks", skip = "wbqd", index = 5일 때, a에서 5만큼 뒤에 있는 알파벳은 f지만 [b, c, d, e, f]에서 'b'와 'd'는 skip에 포함되므로 세지 않습니다. 따라서 'b', 'd'를 제외하고 'a'에서 5만큼 뒤에 있는 알파벳은 [c, e, f, g, h] 순서에 의해 'h'가 됩니다. 나머지 "ukks" 또한 위 규칙대로 바꾸면 "appy"가 되며 결과는 "happy"가 됩니다.
두 문자열 s와 skip, 그리고 자연수 index가 매개변수로 주어질 때 위 규칙대로 s를 변환한 결과를 return하도록 solution 함수를 완성해주세요.
2) 제한 사항
- 5 ≤ s의 길이 ≤ 50
- 1 ≤ skip의 길이 ≤ 10
- s와 skip은 알파벳 소문자로만 이루어져 있습니다.
- skip에 포함되는 알파벳은 s에 포함되지 않습니다.
- 1 ≤ index ≤ 20
3) 입출력 예
s | skip | index | result |
"aukks" | "wbqd" | 5 | "happy" |
2. Solution
1) 내가 푼 정답
using System;
public class Solution {
public string solution(string s, string skip, int index) {
int sCount = s.Length;
int skipCount = skip.Length;
int[] c_s = new int[sCount]; // 배열 크기를 입력해주거나, 값을 할당하던가
int[] c_skip = new int[skipCount];
for (int i = 0; i < sCount; i++)
{
c_s[i] = (int)(s[i]); // (int)로 형 변환
}
for (int i = 0; i < skipCount; i++)
{
c_skip[i] = (int)(skip[i]);
}
string answer = "";
for (int i = 0; i < sCount; i++)
{
int idx = 1;
while (idx <= index)
{
bool same = false;
c_s[i] += 1;
if (c_s[i] > 122) c_s[i] -= 26;
for (int j = 0; j < skipCount; j++)
{
if (c_s[i] == c_skip[j])
{
same = true;
break;
}
}
if (same == false) { idx += 1; }
}
answer += (char)c_s[i]; // string에 char값 추가하기
}
return answer;
}
}
2) 다른 사람 풀이 참고 1
[ System.Linq ] C# Linq 메소드
- Where(), OrderBy(), Select()
- Linq는 C#에서만 사용 가능하다.
- LINQ의 쿼리식인 From, Where, Orderby, Select 등은 System.Linq namespace에 정의되어 있는 IEnumerable<T>의 확장 메소드를 통해 사용 가능하다.
using System;
using System.Linq; // Linq 추가
public class Solution {
public string solution(string s, string skip, int index) {
string answer = "";
string a = new string("abcdefghijklmnopqrstuvwxyz".Where(x => !skip.Contains(x)).ToArray());
// * skip이 x값을 포함하지 않고 있다면
// * ToArray() : List<T>의 요소를 새 배열에 복사합니다.
// 즉, skip이 가지고 있지 않은 알파벳 값만 구성해, 새로운 배열을 만든 것.
foreach (var t in s)
{
answer += a[(a.IndexOf(t.ToString()) + index) % a.Length];
// (1). a.IndexOf(t.ToString()) + index : 배열 a에서 t가 포함된 인덱스 순서를 찾는다. 이후, index만큼 추가를 해준다.
// (2). (1) %a.length : a.Length만큼 나눠서 만약 배열 값보다 커지면, 다시 a부터 값을 찾도록 구성한다.
}
return answer;
}
}
3) 다른 사람 풀이 참고 2
using System;
using System.Linq; // Linq 추가
using System.Collections.Generic; // List<char> 사용
public class Solution {
public string solution(string s, string skip, int index) {
var list = new List<char>(); // char형식 list 배열 생성
// [ skip에 포함되는 알파벳은 s에 포함되지 않으므로 이러한 방법 사용 가능 ]
for (char ch = 'a'; ch <= 'z'; ch++)
{
if (skip.Contains(ch) == false)
{
list.Add(ch); // string skip이 해당 문자를 포함하고 있지 않다면, list 배열에 추가
}
}
return string.Join("", s.Select(c => list[(list.IndexOf(c) + index) % list.Count]));
// string s에 포함된 문자 하나가, list 어디 위치인지 확인한 후 index를 더한다.
// 이후 list.Count를 나눈 나머지의 값의 위치에 있는, list 내 문자를 추가한다. (해당 list 배열을 넘어갈 경우 다시 맨 앞의 문자부터 찾을 수 있도록 하기 위해)
}
}