숫자 차례로 출력하기
문제
- 첫 번째 재귀함수를 이용하여 1부터 N까지 숫자를 차례대로 출력하고, 두 번째 재귀함수를 이용하여 N부터 1까지 출력
포인트
- 재귀호출 위치를 같게 함으로서 다른 파라미터 값을 넣을 수 있다.
- 재귀호출 위치를 다르게 함으로서 같은 파라미터 값을 넣을 수 있다.
풀이1
- 재귀호출 지점을 다르게 하기. 최초 입력 값이 같음.
- asc(int cnt) 함수 : cnt0일때 return되고, 출력하기전 재귀호출하므로, 1부터 출력됨.
import java.util.*;
import java.io.*;
public class Main {
static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
asc(n);
System.out.println();
desc(n);
}
static void asc(int cnt){
if(cnt==0) return;
asc(cnt-1);
System.out.print(cnt+" ");
}
static void desc(int cnt){
if(cnt==0) return;
System.out.print(cnt+" ");
desc(cnt-1);
}
}풀이2
- 재귀 호출 이전 출력하기. 최초 입력 값이 달라짐.
import java.util.*;
import java.io.*;
public class Main {
static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
asc(1);
System.out.println();
desc(n);
}
static void asc(int cnt){
if(cnt==n+1) return;
System.out.print(cnt+" ");
asc(cnt+1);
}
static void desc(int cnt){
if(cnt==0) return;
System.out.print(cnt+" ");
desc(cnt-1);
}
}재귀함수의 꽃
문제
- N이 주어질때, 재귀함수를 단 하나만 이용하여, 아래와 같이 출력.
- N에서 1까지 1씩 감소하며 하나씩 출력했다가, 다시 1부터 N까지 1씩 증가하며 출력
- N N−1 N−2 N−3 … 2 1 1 2 … N−1 N
풀이
- 재귀를 단순히 ‘함수 호출’ 로 생각하지말고,
- 현재 함수 실행을 잠깐 멈춰두고, 더 작은 함수를 끝까지 실행한 뒤, 다시 원래 위치로 돌아오는 것 으로 이해하자.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
print(n);
}
static void print(int cnt){
if(cnt==0) return;
System.out.print(cnt +" ");
print(cnt-1);
System.out.print(cnt +" ");
}
}n=3을 예로 들면
print(3)
3 출력
print(2)
2 출력
print(1)
1 출력
print(0)
return
1 출력
2 출력
3 출력별 출력
문제
- n을 입력받아 예시와 같은 형태로 출력 예시: n=5
* * * * *
* * * *
* * *
* *
*
*
* *
* * *
* * * *
* * * * *풀이
import java.util.*;
import java.io.*;
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());
print(n);
return;
}
static void print(int cnt){
if(cnt==0) return;
for(int i = 0 ; i < cnt ; i++){
System.out.print("* ");
}
System.out.println();
print(cnt-1);
for(int i = 0 ; i < cnt ; i++){
System.out.print("* ");
}
System.out.println();
}
}1부터 N까지의 합
문제
- 1~N까지의 합
풀이
import java.util.*;
import java.io.*;
public class Main {
static int sum,n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
sum = recur(1);
System.out.println(sum);
}
static int recur(int num){
if(num==n) return n;
return num + recur(num+1);
}
}각 자리 숫자의 제곱
문제
- 8자리 이하의 정수 N에 대해 각 자리 숫자의 제곱의 합
풀이
import java.util.*;
import java.io.*;
public class Main {
static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
int ans = recur(n);
System.out.println(ans);
}
static int recur(int num){
if(num == 0) return 0;
return (int)Math.pow(num % 10,2) + recur(num/10);
}
}피보나치
문제
- 재귀 함수로 피보나치 수열을 작성하고 n번째 항의 값을 출력
- 1, 1, 2, 5, 8, …
풀이
import java.util.*;
import java.io.*;
public class Main {
static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
int ans = fib(n);
System.out.println(ans);
}
static int fib(int num){
if(num == 1 || num == 2){
return 1;
}
return fib(num-1) + fib(num-2);
}
}배열의 최대값
문제
- 정수 배열의 최댓값을 재귀함수로 구현
풀이
import java.util.*;
import java.io.*;
public class Main {
static int n, arr[];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
arr = new int[n];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i = 0 ; i < n ; i++){
arr[i] = Integer.parseInt(st.nextToken());
}
System.out.print(recur(0));
return;
}
static int recur(int idx){
if(idx==n-1) return arr[n-1];
return (int)Math.max(arr[idx],recur(idx+1));
}
}- 사고방식 오류와 해결
- 처음엔 최댓값은 두 값을 비교해야 한다는 생각에 끌려서, 종료 조건도 마지막 두 개를 비교하는 형태로 잡았음.
- 그런데 재귀의 종료 조건은 “마지막 연산을 어떻게 할까”가 아니라, 이 함수가 맡은 구간에서 답이 너무 당연해지는 순간으로 잡아야 함.