본문 바로가기
프로그래밍/백준 알고리즘 코드

백준 10872번 자바 팩토리얼 [재귀]

by 졸린이 2021. 6. 3.
반응형

수학2를 마치고 재귀 문제에 들어갔다.

재귀.. 함수가 함수를 호출하고 호출하고 호출하고 리턴하고 리턴하고 리턴하는 생각하기 너무 귀찮은 뭐 그렇다.

팩토리얼 프로그램을 작성하는 것이다.

참고로 팩토리얼은 ! 로 표시하는데 3! 이면 1 * 2 * 3 = 으로 6 이다.

5! 은 1*2*3*4*5 이다.

 

첫 줄에 n을 입력하면 n!을 출력하면 된다.

1*2* ... * n을 출력하면 되는데 그럼 간단하게 for문으로도 작성할 수 있다.

[for 문]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.Scanner;
 
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
       
        int n = sc.nextInt();
        
        int pact = 1;
        
        for(int i=1; i<=n; i++) {
            pact *= i;
        }
        System.out.println(pact);
    }
}
cs

이렇게 하면 간단하게 풀 수 있다. 그래도 문제가 재귀니까 재귀함수를 만들어서도 한 번 풀어보자.

[재귀]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Scanner;
 
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
       
        int n = sc.nextInt();
        
        System.out.println(pactorial(n));
    }
    
    static int pactorial(int n) {
        if(n == 1)
            return 1;
        return n * pactorial(n-1);
    }    
}
 
cs

간단하게 설명하면 pactorial(3)을 호출하면 함수가 3을 받아서 n이 1이 아니므로 n * pact(n-1)을 호출한다.

[3 * pact(3-1)에서의 리턴값] 이므로 pact(2)에서 리턴받는 값을 곱해준다. 마찬가지로 n은 2이라서 if문을 안타고 다시 2-1로 함수를 호출한다.

 

이렇게 함수가 자신의 함수를 호출하고 호출하는게 재귀함수이다.

2가 다시 함수안으로 들어가서 [2 * pact(2-1)] 을 호출한다. 그럼 1이 들어와서 1을 리턴하고

2 * 1을 리턴하고 3 * 2까지 와서 곱해주고 최초 호출한대로 리턴해서 6이 출력된다.

결과는 for문으로 작성한 것은 정답으로 채점 되었으나 재귀함수는 런타임 에러가 떴다.

ㅎㅎㅎㅎ

그러면 이 문제는 재귀로 풀 수 없을까?? 아니 자바에서 런타임 에러가 뜨면 기본적으로 버퍼를 사용해보면 된다.

[Buffered 재귀]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
 
public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     
        
        int n = Integer.parseInt(br.readLine());
        
        System.out.println(Pactorial(n));
        
    }
    static int Pactorial(int n) {
        if(n ==0)
            return 1;
        else
            return n * Pactorial(n-1);
    }
}
cs

위에 작성한 것과 같은 코드이지만 다른점은 Scanner를 사용하지 않고 BufferedReader를 사용했다는 점이다.

맨 아래 for문 그 다음 재귀 그 다음 버퍼리더를 사용한 재귀함수이다.

시간을 확인해보면 확실히 버퍼를 사용하면 시간이 좀 줄긴한다.

결론으로는 이 문제를 풀면서 쉽게 쉽게 생각하고 쉽게 가야하는 교훈을 얻었다. for문이 어때서.... 후.

 

반응형

댓글