Code KATA/알고리즘 코드카타

[2024.12.18] 자연수 뒤집어 배열로 만들기

iiblueblue 2024. 12. 18. 12:33

문제 설명

자연수 n을 뒤집어 각 자리 숫자를 원소로 가지는 배열 형태로 리턴해주세요. 예를들어 n이 12345면[5, 4, 3, 2, 1]을 리턴합니다.

 

 

제한사항

  • n은 10,000,000,000이하인 자연수입니다.

 

 

입출력 예

n return
12345 [5, 4, 3, 2, 1]

 

 

문제 풀이

풀이 언어 : C++

#include <string>
#include <vector>
#include <cmath>

using namespace std;

vector<int> solution(long long n) {
    vector<int> answer;
    long long myN=n;
    int insertNum;
    int lengthOfN=to_string(n).size();
    
    for(int i=lengthOfN-1; i>-1; i--)
    {
        insertNum=myN/pow(10, i);
        answer.insert(answer.begin(), insertNum);
        myN-=insertNum*pow(10, i);
    }
    return answer;
}

이전에 풀이했던 자릿수 더하기와 비슷한 방법으로 문제를 풀면 되겠다고 생각했다.

https://iiblueblue.tistory.com/64

 

[2024.12.14] 자릿수 더하기

문제 설명자연수 N이 주어지면, N의 각 자릿수의 합을 구해서 return 하는 solution 함수를 만들어 주세요.예를 들면 N=123이면 1+2+3=6을 return 하면 됩니다   제한사항N의 범위 : 100,000,000 이하의 자연

iiblueblue.tistory.com

n의 가장 큰 자릿수부터 나누기로 자릿수를 하나씩 뽑아내고, n에서 뽑아낸 자릿수를 뺀 나머지를 이용해 다시 이 과정을 반복하는 방법이다. 문제는 벡터에 저장될 때 가장 큰 자릿수가 뒤에 있어야 한다는 것이었다. 그 문제는 insert() 함수를 이용해 해결할 수 있었다.

 

자릿수 뽑아내기

먼저 이전 자릿수 더하기와 비슷하게 풀이하기 위해 myN과 insertNum 변수를 선언한다. myN은 직접 수정할 수 없는 n을 위한 변수이기 때문에 n으로 초기화 한다.

for문은 n이 몇 자릿수인지 확인하고 그보다 하나 적은 수부터 시작하여 줄어들어 0까지 반복하도록 하였다. 입출력 예를 생각하면 5 자릿수 이기 때문에 4에서 0까지 반복하게 되는 것이다.

그 안에서는 이전과 같이 myN에서 pow 함수를 이용하여 10의 i제곱 수 빼 추출해낸 자릿수를 insertNum에 저장하는 작업을 한다. 또한 myN을 이전 myN에서 추출한 자릿수를 제거하는 과정도 거쳐 myN을 업데이트해준다.

 

먼저 추출한 자릿수(가장 큰 자리 자릿수)가 제일 뒤로 가게 하기

그 사이에 insert() 함수를 이용하여 새로운 insertNum은 벡터의 가장 앞 부분에 끼워넣어 지도록 하였다. 이렇게하면 자릿수가 점점 작아지면서 작은자리 자릿수들이 앞에 끼워넣어지기 때문에 결론적으로 가장 먼저 구해진 가장 큰 자리 자릿수가 제일 뒤에 위칙하게 할 수 있다.

 

n이 몇 자릿수인지 확인하기

마지막으로 풀이 중 마주친 문제가 하나 더 있었다. for문을 돌리기 위해 필요한 n이 몇 자릿수인지 계산하는 방법을 몰라 당황했다. 하지만 생각보다 간단한 방법으로 문제를 해결했다.

n을 string 데이터 타입으로 변경해준 후 string 형이 된 n이 몇글자나 되는지 size() 함수로 알아보는 것이다. 나도 검색해보고서야 알게된 방법인데 이후에도 필요할 때 유용하게 사용할 것 같다.

 

이전 자릿수 더하기에서도 이 방법을 사용하면 반복문을 덜 돌리면서 구현할 수 있을 것 같다.

 

참고사항

insert(iterator position, const T& x) 함수는 vector에 값을 추가할 때 원하는 위치에 값을 끼워넣을 수 있는 함수다. position에 원하는 위치를 넣고 x 값에 원하는 값을 넣으면 된다. vector의 함수를 사용하여 begin(), end()를 사용할 수도 있지만 다른 위치를 원한다면 iterator를 선언하거나 begin()+n하면 n번째에 추가할 수 있다.

...
vector<int> v(3, 1);
vector<int>::iterator it=v.begin();
...

// 하나 삽입하기
v.insert(v.begin(), 3); // 맨 앞에 하나 삽입
v.insert(it, 3);

// 두개 이상 삽입하기
v.insert(it, 2, 3); // 맨 앞에 여러개 삽입(2를 3개 삽입)
v.insert(it+2, 2, 4) // 3번째부터 여러개 삽입(2를 4개 삽입)

// 배열 이용하기
int arr[]={1, 2, 3, 4};
v.insert(v.begin(), arr, arr+4); // 맨 앞에 배열 삽입
...

 

 

오답노트

n이 몇 자릿수인지 확인하지 않고 최대의 경우로 반복문을 돌려 뒤에 불필요한 0 값까지 전부 벡터에 들어가게 되어 결과값에 문제가 있었다.

...
    for(int i=lengthOfN-1; i>-1; i--)
    {
        insertNum=myN/pow(10, i);
        // 0인 경우 저장하지 않고 넘어가기
        if(insertNum==0)
        {
            continue;
        }
        answer.insert(answer.begin(), insertNum);
        myN-=insertNum*pow(10, i);
    }
    return answer;
...

불필요하게 들어간 0을 삭제하겠다고 insertNum이 0인 경우 벡터에 추가하지 않고 넘어가게 하였는데 12043과 같이 중간에 0이 포함된 수에서는 중간에 0은 벡터에 포함되어야 하는 이유로 결과값에 오류가 있었다.

 

 

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/12932

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr