🧩 μ•Œκ³ λ¦¬μ¦˜

μž¬κ·€λž€?

seonghye0n 2023. 5. 17. 21:27
μ˜€λŠ˜μ€ μž¬κ·€μ— λŒ€ν•΄μ„œ 정리해보렀고 ν•œλ‹€.
μž¬κ·€λŠ” μ½”ν…Œμ—μ„œ κ°€μž₯ 많이 λ‚˜μ˜€λŠ” DFS, BFSλ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œ λ°˜λ“œμ‹œ μ•Œμ•„μ•Ό ν•˜λŠ” λ‚΄μš©μ΄κΈ° λ•Œλ¬Έμ— μ •λ¦¬ν•œ 후에도 계속 μ—¬λŸ¬ μ˜ˆμ œλ“€μ„ ν’€μ–΄λ³΄λ©΄μ„œ μŠ΅λ“ν•΄μ•Όλ  것 κ°™λ‹€.

 

μž¬κ·€λŠ” μ‰½κ²Œ λ§ν•΄μ„œ 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.

예λ₯Ό λ“€μ–΄, 1λΆ€ν„° 10κΉŒμ§€ λ”ν•˜μ—¬ 좜λ ₯ν•˜λ„λ‘ μž‘μ—…ν•œλ‹€λ©΄ μ•„λž˜μ™€ 같이 for문을 μ΄μš©ν•˜μ—¬ 좜λ ₯ν•˜λŠ”κ²Œ λ¨Όμ € λ– μ˜€λ₯Ό 것이닀.

public class Main {
	public static void main(String[] args) {
		System.out.println(loop());
	}

	public static int loop() {
		int n = 0;

		for (int i = 1; i <= 10; i++) {
			n += i;
		}

		return n;
	}
}

 

그리고 이것을 μž¬κ·€λ₯Ό μ΄μš©ν•˜μ—¬ μž‘μ—…ν•œλ‹€λ©΄ μ•„λž˜μ™€ 같은 μ½”λ“œλ‘œ ν•  수 μžˆλ‹€.

public class Main {
	public static void main(String[] args) {
		System.out.println(recursion(10));
	}

	public static int recursion(int n) {
		if (n == 1) return 1;

		return n + recursion(n - 1);
	}
}

이 예제λ₯Ό 보면 recursion λ©”μ„œλ“œ μ•ˆμ—μ„œ n += recursion(n + 1), 즉 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜λŠ” 것을 μ•Œ 수 μžˆλ‹€.

그리고 자기 μžμ‹ μ„ ν˜ΈμΆœν•œλ‹€λŠ” μ μ—μ„œ λ­”κ°€ 반볡적인 λ™μž‘μ„ ν•œλ‹€λŠ” 것을 눈치챌 수 μžˆμ„ 것이닀.

μ•Œκ³ λ¦¬μ¦˜ 문제λ₯Ό 풀닀보면 λ¬Έμ œμ—μ„œ λ­”κ°€ λΉ„μŠ·ν•œ λ‚΄μš©μ΄ 꼬리에 꼬리λ₯Ό λ¬΄λŠ” ν˜•νƒœλΌλ©΄ μž¬κ·€ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ ν’€ 수 μžˆλŠ”μ§€ λ¨Όμ € 고렀해봐야 ν•œλ‹€.


κ·Έλ ‡λ‹€λ©΄ μž¬κ·€ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ–΄λ–€ μž₯점이 있고 단점이 μžˆμ„κΉŒ??

 

μž₯점

λ°˜λ³΅λ¬Έμ„ μ‚¬μš©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ½”λ“œκ°€ κ°„κ²°ν•΄μ§„λ‹€.

- μœ„μ˜ μ•„μ£Ό κ°„λ‹¨ν•œ 예제만 봐도 μž¬κ·€ν•¨μˆ˜λ₯Ό μ΄μš©ν•œκ²Œ 더 간결해보이지 μ•Šλ‚˜ 생각이 λ“ λ‹€.

 

단점

속도가 λŠλ¦¬λ‹€.

- κ²°κ΅­ λ©”μ„œλ“œλ₯Ό 계속 ν˜ΈμΆœν•˜λŠ” 것이기 λ•Œλ¬Έμ— λ°˜λ³΅ν•˜λŠ” 만큼 μŠ€νƒμ— μŒ“μ΄κ²Œ λœλ‹€. λ©”λͺ¨λ¦¬λ₯Ό 그만큼 μ‚¬μš©ν•˜λ‹€λ³΄λ‹ˆ 속도가 μ €ν•˜λ  수 밖에 μ—†λ‹€. 심지어 λ¬΄λ¦¬ν•˜κ²Œ ν˜ΈμΆœν•˜λ©΄ Stack Overflow 였λ₯˜κ°€ λ°œμƒν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ 이 λ¬Έμ œλŠ” 꼬리 μž¬κ·€λ₯Ό μ΄μš©ν•˜μ—¬ μ΅œμ ν™”κ°€ κ°€λŠ₯ν•˜λ‹€.


꼬리 μž¬κ·€

꼬리 μž¬κ·€λŠ” 호좜이 λλ‚˜λ©΄ 결과만 λ°”λ‘œ λ°˜ν™˜ν•˜λ„λ‘ ν•˜λŠ” 방법이닀. 더 μ„€λͺ…해도 와닿지 μ•ŠκΈ° λ•Œλ¬Έμ— μ•„λž˜ 예제λ₯Ό 톡해 μžμ„Ένžˆ μ„€λͺ…해보렀고 ν•œλ‹€.

μž¬κ·€ν•¨μˆ˜μ˜ λŒ€ν‘œμ μΈ 예제인 νŒ©ν† λ¦¬μ–Όλ‘œ μ„€λͺ…ν•˜λ €κ³  ν•œλ‹€.

 

μ•„λž˜ μ½”λ“œλŠ” 일반적인 μž¬κ·€ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ κ΅¬ν˜„ν•œ 것이닀.

	public static int factorial(int n) {
		if (n == 1) return 1;

		return n * factorial(n - 1);
	}

ν•΄λ‹Ή μ½”λ“œκ°€ μ–΄λ–»κ²Œ λ‚΄λΆ€μ μœΌλ‘œ λ™μž‘λ˜λŠ”μ§€ 보면, factorial(3)을 ν˜ΈμΆœν–ˆλ‹€κ³  κ°€μ •ν•˜μž.

μž¬κ·€ν•¨μˆ˜λŠ” 3 * factorial(2) / 3 * (2 * factorial(1))  / 3 * (2 * 1 ) / 3 * 2 / 6 μ΄λŸ°μ‹μœΌλ‘œ 호좜 λ‹Ήν•œ ν•¨μˆ˜κ°€ ν˜ΈμΆœν•œ ν•¨μˆ˜μ—κ²Œ μžμ‹ μ˜ 결과값을 μ•Œλ €μ£Όκ³ , κ·Έ 값을 전달받은 ν•¨μˆ˜λŠ” μžκΈ°κ°€ κ°€μ§€κ³  있던 κ°’κ³Ό 계산을 ν•΄μ„œ λ‹€μ‹œ λ‹€λ₯Έ ν•¨μˆ˜μ—κ²Œ 전달을 ν•œλ‹€.

 

μ΄λ²ˆμ—λŠ” 꼬리 μž¬κ·€λ₯Ό μ΄μš©ν•˜μ—¬ μ•„λž˜μ™€ 같이 κ΅¬ν˜„ν–ˆλ‹€.

	public static int factorialTail(int n, int result) {
		if (n == 1) return result;

		return factorialTail(n - 1, n * result);
	}

λ”± 봀을 λ•Œ λ³΄μ΄λŠ” 차이점이 μžˆμ„ 것이닀. λ°”λ‘œ λ§€κ°œλ³€μˆ˜μ— κ³„μ‚°ν•œ 결과값을 κ°€μ§€κ³  μžˆλ„λ‘ ν•œ 것인데, μœ„μ—μ„œ μ„€λͺ…ν–ˆλ“―이 꼬리 μž¬κ·€λŠ” 호좜이 λλ‚˜λ©΄ 결과만 λ°”λ‘œ λ°˜ν™˜ν•˜λ„λ‘ ν•˜λŠ” 방법이닀.

꼬리 μž¬κ·€κ°€ μ–΄λ–»κ²Œ λ‚΄λΆ€μ μœΌλ‘œ λ™μž‘λ˜λŠ”μ§€ 보자. λ˜‘κ°™μ΄ factorialTail(3, 1)을 ν˜ΈμΆœν–ˆλ‹€κ³  κ°€μ •ν•˜μž.

꼬리 μž¬κ·€λŠ” factorial(3, 1) / factorial(2, 3) / factorial(1, 6) / 6 / 6 / 6 μ΄λŸ°μ‹μœΌλ‘œ μΌλ°˜μž¬κ·€μ™€ λ‹€λ₯΄κ²Œ μ–΄λ–€ 연산을 ν•˜μ§€ μ•Šκ³  값을 μ „λ‹¬ν•˜λŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

 

μ°Έκ³ 

λ°±μ€€ - μž¬κ·€ κ΄€λ ¨ 문제 리슀트

https://www.acmicpc.net/problemset?sort=ac_desc&algo=62 

 

문제 - 1 νŽ˜μ΄μ§€

 

www.acmicpc.net

 

λ°˜μ‘ν˜•