https://www.acmicpc.net/problem/11005
11005번 진법 변환 2
10진법 수를 B진법으로 바꿔서 출력하는 문제이다.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int N, B;
cin >> N >> B;
vector<char> v;
int a = N % B;
do {
N /= B;
char c;
if (a > 9) {
c = 'A' + (a - 10);
}
else {
c = a + '0';
}
v.push_back(c);
a = N % B;
} while (N >= B || a != 0);
for (auto i = v.rbegin(); i != v.rend(); ++i) {
cout << *i;
}
}
10진법으로 들어온 수를 B진법으로 출력해야 한다.
B가 10이 초과되는 값이 들어온다면 알파벳 대문자를 사용해야 하기 때문에 수를 char 형으로 출력하도록 했다.
출력할 값을 저장할 char 형 vector를 선언해서 값을 저장하도록 했다.
내가 이 문제를 풀기 위해 사용한 특징은 B진법의 수는 각 자리의 수가 B를 넘지 않는다는 점이다.
즉, 들어온 N에 B를 나머지 연산을 계속 수행하면 일의 자리부터 구할 수 있다는 점이다.
(나머지 연산을 한 번 수행하면 나누기 연산도 해서 몫을 계속 갱신해야 한다.)
이렇게 구한 나머지의 값을 char형으로 변환해야 한다.
값이 9를 초과하면 char 형으로 출력할 때 표현하고자 하는 수에 맞는 아스키코드의 값을 입력해야 하고,
9 이하라면 정수로 들어온 값을 문자형의 숫자로 변환하는 과정을 거쳐야 한다.
아래의 코드가 해당 작업을 수행하는 코드이다.
if (a > 9) {
c = 'A' + (a - 10);
}
else {
c = a + '0';
}
나머지 값을 구하고, 나눈 값을 갱신하는 과정을 언제까지 하는지 조건을 설정해두었다.
N이 B와 같거나 클 때, 혹은 나머지 값이 0이 아닐 때만 반복해야한다.
입력으로 들어온 10진법 수 N이 B보다 작을 수 있으므로, 한 번은 무조건 실행하도록 do while 문으로 작성했다.
또한 N이 B보다 작은데 나머지(a)가 0이 아니라면 다음 루프에서 해당 수를 push_back 해주어야 한다.
아래의 코드가 해당 do while 문이다.
일단 무조건 한 번은 실행하기 때문에 루프에 진입하기 전에 나머지 연산을 해준다.
다음 루프에서 사용할 나머지 값을 루프의 마지막에 계산한다.
int a = N % B;
do {
N /= B;
char c;
if (a > 9) {
c = 'A' + (a - 10);
}
else {
c = a + '0';
}
v.push_back(c);
a = N % B;
} while (N >= B || a != 0);
위의 do while 문이 끝났다면 변환한 값을 출력하기만 하면 된다.
나는 B로 나눈 나머지를 B진법으로 변환한 후에 push_back 하였으므로, 낮은 자리수가 낮은 index 의 자리에 들어간다.
즉, 출력할 때는 높은 index의 원소부터 출력해야 한다는 것이다.
그래서 vector의 원소에 접근할 때 rbegin() 과 rend() 를 통해서 거꾸로 접근하도록 한다.
for 문의 i를 auto로 rbegin() 이 반환한 타입을 사용하도록 코딩했다.
그래서 for 문으로 순회할 때 전위증가연산자를 이용해도 문제 없다.
for (auto i = v.rbegin(); i != v.rend(); ++i) {
cout << *i;
}
이 문제를 풀면서 내가 범했던 실수는..
while 문의 조건을 N과 B가 같은 경우를 제외하도록 설정했다.
이를 제외하면 가장 높은 자리 수를 계산할 때, 나머지가 0이 아닐 때의 경우를 포함하지 않아서 잘못된 값이 나온다.
마치며..
B진법의 수를 10진법으로 변환하는 문제와 매우 비슷해서 접근법을 찾는게 어렵지 않았다.
B진법의 수를 10진법으로 변환하는 일은 평상시에도 공부하면서 필요한 지식이었고,
(가령 2진법의 수를 10진법으로 변환하거나 16진법의 수를 10진법의 수로 변환하는 경우말이다.
내가 평소에 사용하는 방법을 알고리즘 화 했다.)
반대의 경우인 지금의 문제도 공부하면서 꽤나 필요했기 때문에 어렵지 않게 접근할 수 있었다.
그런 김에 B 진법의 수를 10진법의 수로 변환하는 문제의 URL을 첨부한다.
(이걸 위한 빌드업이었다.)
https://zinistic.tistory.com/37
백준 2745번 진법 변환 (C++)
이전 포스팅들은 각 단계별로 묶어서 업로드 했는데, 각 문제들에서 시사할 바와 내가 고민한 바 등등 적고싶은게 많아졌다. 한 문제당 고봉밥(최대한;;)으로 업로드 하는 형식으로 변경하려고
zinistic.tistory.com
** 오류 지적은 환영입니다. ^^ **
'코테' 카테고리의 다른 글
백준 2903번 중앙 이동 알고리즘 (C++) (0) | 2025.03.22 |
---|---|
백준 2720번 세탁소 사장 동혁 (C++) (0) | 2025.03.21 |
백준 2745번 진법 변환 (C++) (0) | 2025.03.19 |
백준 단계별로 풀어보기 (7) (0) | 2025.03.18 |
백준 단계별로 풀어보기 (6) (1) | 2024.09.25 |