문과 코린이의, [C#] 기록/C# CodingTest

[문과 코린이의 IT 기록장] C# 프로그래머스(Programmers) - 둘만의 암호

벼리네 2023. 2. 9. 11:16
반응형

[문과 코린이의 IT 기록장] C# 프로그래머스(Programmers) - 둘만의 암호

 


 

코딩테스트 연습 | 프로그래머스 스쿨

개발자 취업의 필수 관문 코딩테스트를 철저하게 연습하고 대비할 수 있는 문제를 총망라! 프로그래머스에서 선발한 문제로 유형을 파악하고 실력을 업그레이드해 보세요!

school.programmers.co.kr


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 배열을 넘어갈 경우 다시 맨 앞의 문자부터 찾을 수 있도록 하기 위해)
    }
}
반응형