|
| 1 | +# 자릿수 |
| 2 | + |
| 3 | +`N = 2019`이라고 할 때, `N`의 자릿수는 4이고, 각 자리의 숫자는 `2`, `0`, `1`, `9`이다. |
| 4 | + |
| 5 | +몇 가지 예시를 보면: |
| 6 | + |
| 7 | +``` |
| 8 | +N = 00 [영(零)] |
| 9 | +자릿수 = 0 |
| 10 | +
|
| 11 | +N = -123 [음수] |
| 12 | +자릿수 = 3 |
| 13 | +
|
| 14 | +N = 10000 [양수] |
| 15 | +자릿수 = 5 |
| 16 | +``` |
| 17 | + |
| 18 | +## 간단한 방법 |
| 19 | + |
| 20 | +가장 먼저 떠오르는 방법은 간단하다: |
| 21 | + |
| 22 | + 1. 숫자 N이 0인지 확인한다. |
| 23 | + 2. N이 0이 아닌 경우, 자릿수를 1 늘린다. |
| 24 | + 3. N을 10으로 나눈다. |
| 25 | + 4. N이 0이 될 때까지 위의 과정을 반복한다. |
| 26 | + |
| 27 | +**알고리즘 분석:** 위 방법에서 수행되는 작업의 수는 숫자 N의 자릿수와 같다는 사실을 쉽게 알 수 있다. 따라서 이 방법의 시간 복잡도는 $O(자릿수)$이다. |
| 28 | + |
| 29 | +**모의 실행:** `N = 58964`라고 할 때, |
| 30 | + |
| 31 | +자릿수를 저장할 변수 `digitsCount`를 0으로 초기화하고, `N`이 0이 아닌 동안 반복적으로 `digitsCount`를 늘리고 `N`을 10으로 나눈다. |
| 32 | + |
| 33 | +``` |
| 34 | +Iteration 1: N not equals to 0 |
| 35 | +Increment digitsCount, digitsCount = digitsCount + 1. |
| 36 | +digitsCount = 0 + 1 = 1. |
| 37 | +N = N/10 = 58964/10 = 5896. |
| 38 | +
|
| 39 | +Iteration 2: N not equals to 0 |
| 40 | +Increment digitsCount, digitsCount = digitsCount + 1. |
| 41 | +digitsCount = 1 + 1 = 2. |
| 42 | +N = N/10 = 5896/10 = 589. |
| 43 | +
|
| 44 | +Iteration 3: N not equals to 0 |
| 45 | +Increment digitsCount, digitsCount = digitsCount + 1. |
| 46 | +digitsCount = 2 + 1 = 3. |
| 47 | +N = N/10 = 589/10 = 58. |
| 48 | +
|
| 49 | +Iteration 4: N not equals to 0 |
| 50 | +Increment digitsCount, digitsCount = digitsCount + 1. |
| 51 | +digitsCount = 3 + 1 = 4. |
| 52 | +N = N/10 = 58/10 = 5. |
| 53 | +
|
| 54 | +Iteration 5: N not equals to 0 |
| 55 | +Increment digitsCount, digitsCount = digitsCount + 1. |
| 56 | +digitsCount = 4 + 1 = 5. |
| 57 | +N = N/10 = 5/10 = 0. |
| 58 | +
|
| 59 | +Iteration 6: N becomes equal to 0. |
| 60 | +Terminate any further operation. |
| 61 | +Return value of digitsCount. |
| 62 | +``` |
| 63 | + |
| 64 | +그러므로 `N`의 자릿수는 5이다. |
| 65 | + |
| 66 | +## 더 나은 방법 |
| 67 | + |
| 68 | +수학을 활용하면 더 나은 방법을 찾을 수 있다. N의 자릿수는 다음의 공식으로 쉽게 구할 수 있다: |
| 69 | + |
| 70 | +``` |
| 71 | +N의 자릿수 = log10(N) + 1. |
| 72 | +``` |
| 73 | + |
| 74 | +**유도:** `N`의 자릿수를 `K`라고 하면: |
| 75 | + |
| 76 | +``` |
| 77 | +10^(K-1) <= N < 10^K |
| 78 | +``` |
| 79 | + |
| 80 | +위 부등식의 양변에 상용로그(밑이 10인 로그)를 취하면: |
| 81 | + |
| 82 | +``` |
| 83 | +K - 1 <= log10(N) < K. |
| 84 | +
|
| 85 | +또는, K - 1 + 1 <= log10(N) + 1 < K + 1 |
| 86 | +또는, K <= log10(N) + 1 < K + 1 |
| 87 | +``` |
| 88 | + |
| 89 | +그러므로, |
| 90 | + |
| 91 | +``` |
| 92 | +K = floor(log10(N) + 1) |
| 93 | +``` |
| 94 | + |
| 95 | +**알고리즘 분석:** 위 방법은 `로그`와 `버림`이라는 수학적인 함수를 사용한다. 그러므로 이 방법의 시간 복잡도는 두 함수의 복잡도에 따라 달라진다. 버림함수는 소수점 이하의 숫자들을 버리기만 하면 되기 때문에 사실상 항상 일정한 시간이 걸린다 (적어도 그렇게 만들기 쉽다). 일반적으로 고정폭 부동 소수점 값을 사용하기 때문에 실용적으로는 `로그함수도 일정한 시간이 걸린다고 가정`할 수 있다. 하지만 임의 정밀도 "큰 수" 라이브러리를 사용하면, 사용되는 로그 알고리즘에 따라 로그함수의 성능이 달라질 수 있다. |
| 96 | + |
| 97 | +## 영상 URL |
| 98 | + |
| 99 | +- [Programming Tutorials (C, C++)](https://www.youtube.com/watch?v=ngWnvWR8NkE) |
| 100 | + |
| 101 | +## 출처 |
| 102 | + |
| 103 | +- [GeeksforGeeks](https://www.geeksforgeeks.org/program-count-digits-integer-3-different-methods/) |
0 commit comments