문제 풀기/C#

104. 소수 찾기(재귀 함수를 이용한 소수 만들기)

kagan-draca 2025. 4. 1. 17:11

 

문제를 보고 소수를 만들 방법에 대해 많은 고민을 했다.

 

재귀함수를 사용해서 소수를 만들어야 하는 상황이라 

 

매개변수로 무슨 값을 줘야할지 많이 고민했다.

 

고민 끝에 나온 결론으로는 

 

1. 제한 시킬 글자 수

2. 현재 만들어진 숫자(문자열)

3. numbers(제공 될 문자열)

 

로 선택했다.

 

재귀함수의 반환형은 void로 설정 했는데 이유는 딱히 반환해야 할 내용이 없어 보였기 때문이다.

 

    // 필요한 매개변수
    // 제한 시킬 글자 수
    // 현재 만들어진 숫자(문자열)
    // numbers(제공 될 문자열)
    public void MakeNumber(int length, string currentWords, string numbers) {
        
        if(currentWords.Length == length + 1) return;
        
    }

 

먼저 현재 만들어진 문자열의 길이가 제한된 문자열의 길이 보다 1 클 경우 함수를 종료하도록 만들었다.

 

(

 

처음에는 현재 만들어진 문자열의 길이가 제한된 길이와 같으면 종료로 설정했는데 그럴 경우

제한된 사이즈 만큼 완성된 문자열을 hashSet에 저장하지 못 하는 문제가 존재했다.

 

)

 

    // 필요한 매개변수
    // 제한 시킬 글자 수
    // 현재 만들어진 숫자(문자열)
    // numbers(제공 될 문자열)
    public void MakeNumber(int length, string currentWords, string numbers) {
        
        if(currentWords.Length == length + 1) return;
        
        int.TryParse(currentWords, out int result);
        if(result != 0 && result != 1) hashSet.Add(result);
        
 	}

 

그 후, 현재 만들어진 숫자(string 타입)이 int.Parse이 아니라 int.TryParse을

 

사용해 "" 같은 공백 오류를 제거한 int형 정수 중 0과 1을 제외하고 hashSet에 저장해줬다.

(공백은 0으로 변환된다)

 

    // 필요한 매개변수
    // 제한 시킬 글자 수
    // 현재 만들어진 숫자(문자열)
    // numbers(제공 될 문자열)
    public void MakeNumber(int length, string currentWords, string numbers) {
        
        if(currentWords.Length == length + 1) return;
        
        int.TryParse(currentWords, out int result);
        if(result != 0 && result != 1) hashSet.Add(result);
        
        for(int i = 0; i < numbers.Length; i++)
        {
            MakeNumber(length, currentWords + numbers[i], numbers.Remove(i, 1));
        }
    }

 

마지막으로 for과 재귀함수를 사용해 추가할 숫자를 지정한 후 numbers.Remove(i,1)로 사용된 숫자는 제거해줬다.

 

( Remove(i, 1) 중요!! 안 쓰면 사용된 숫자가 다시 사용되는 현상이 발생 합니다!)

 

이렇게 만들어진 hashSet의 요소들을 

 

    public int IsPrime(int number)
    {
        bool check = true;
        for(int i = 2; i <= (int)Math.Sqrt(number); i++)
        {
            if(number % i == 0) check = false;
        }
        return check ? 1 : 0;
    }

 

소수를 판별하는 함수에 집어 넣고 소수이면 1, 아니면 0을 반환시켜준다.

 

    public int solution(string numbers) {
        int answer = 0;
        
        MakeNumber(numbers.Length, "",numbers);
        
        foreach(int element in hashSet)
        {
            answer += IsPrime(element);
        }
        
        return answer;
    }

 

반환 받은 숫자를 answer에 추가 할 수 있게 만들어 결과를 도출하면 된다.

 

전체 코드 :

 

using System;
using System.Collections.Generic;

public class Solution {

    public HashSet<int> hashSet = new HashSet<int>();
    
    // 필요한 매개변수
    // 제한 시킬 글자 수
    // 현재 만들어진 숫자(문자열)
    // numbers(제공 될 문자열)
    public void MakeNumber(int length, string currentWords, string numbers) {
        
        if(currentWords.Length == length + 1) return;
        
        int.TryParse(currentWords, out int result);
        if(result != 0 && result != 1) hashSet.Add(result);
        
        for(int i = 0; i < numbers.Length; i++)
        {
            MakeNumber(length, currentWords + numbers[i], numbers.Remove(i, 1));
        }
    }
    
    public int IsPrime(int number)
    {
        bool check = true;
        for(int i = 2; i <= (int)Math.Sqrt(number); i++)
        {
            if(number % i == 0) check = false;
        }
        return check ? 1 : 0;
    }
    
    public int solution(string numbers) {
        int answer = 0;
        
        MakeNumber(numbers.Length, "",numbers);
        
        foreach(int element in hashSet)
        {
            answer += IsPrime(element);
        }
        
        return answer;
    }
}