Lv 0. 배열 회전시키기 - deque를 쓸려면 <deque> 헤더를 추가하자. 시퀀스 컨테이너에서 rotate() 함수 사용법

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

 

deque를 사용한 풀이를 이용하지 않더라도 풀 수 있는 문제로 보였는데, 처음에 생각난 풀이가 deque를 사용하듯이 앞뒤에서 내장함수를 이용해서 추가하고 빼고 하는 형태의 풀이를 떠올려서 그에 맞는 풀이를 먼저 제출해보다보니 deque를 이용한 풀이를 하게 되었다. 

vector에도 원소를 앞뒤에서 빼고 넣고 하는 형태의 함수가 있을것 같다는 생각에 작성한 코드 형태인데, 해당 함수가 없다고 해서(명확한 이름을 몰랐을수도 있다) deque로 방향을 전환한 것이고, 아래와 같은 코드를 제출해서 통과할 수 있었다. 

#include <string>
#include <vector>
#include <deque>

using namespace std;

vector<int> solution(vector<int> n, string d) {
    deque<int> dq;
    for(auto c: n){
        dq.push_back(c);
    }
    if(d=="right"){
        dq.push_front(dq.back()); dq.pop_back();
    }
    else{
        dq.push_back(dq.front()); dq.pop_front();
    }
    vector<int> answer;
    for(auto c: dq)
        answer.push_back(c);
    return answer;
}

 

 

이제 이 문제에 대해서 다른 사람들은 어떻게 해결했는지 찾아보니, 가장 처음으로 올라와 있는 풀이가 바로 

rotate() 함수를 이용한 풀이였다. 

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> solution(vector<int> numbers, string direction) {
    if(direction =="left")
        rotate(numbers.begin(),numbers.begin()+1,numbers.end());
    else
        rotate(numbers.begin(),numbers.end()-1,numbers.end());
    return numbers;
}

 

이때에 rotate() 함수에 대해서 검색을 해보면, 

C++의 `rotate()` 함수는 시퀀스 컨테이너 (예: 배열, 벡터, 덱 등) 내의 요소를 회전(rotate)시키는 데 
사용됩니다. 이 함수는 C++ 표준 라이브러리의 `<algorithm>` 헤더에 포함되어 있습니다.

`rotate()` 함수는 다음과 같이 선언됩니다:

```cpp
template <class ForwardIterator>
void rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last);
```

여기서:

- `first`: 회전을 수행할 시퀀스의 시작 요소를 가리키는 반복자(iterator).
- `middle`: 회전 중심이 될 요소를 가리키는 반복자(iterator). 이 요소를 중심으로 왼쪽과 오른쪽의 
요소가 서로 위치를 바꿉니다.
- `last`: 시퀀스의 마지막 요소를 가리키는 반복자(iterator).

`rotate()` 함수는 시퀀스를 회전시켜서 `first`와 `middle` 사이의 요소를 `middle`와 
`last` 사이의 요소와 위치를 바꿉니다.

예를 들어, 다음과 같이 사용할 수 있습니다:

```cpp
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::rotate(numbers.begin(), numbers.begin() + 2, numbers.end());

    for (const int& num : numbers) {
        std::cout << num << " ";
    }

    return 0;
}
```

이 코드는 `numbers` 벡터를 회전시켜서 결과를 출력합니다. `rotate()` 함수를 사용하면 컨테이너의 
요소를 효과적으로 회전시킬 수 있습니다.

 

위와 같은 정보를 종합해볼때, roatate() 함수는 <algorithm> 헤더에 있는데, 이때에 사용법에서 가운데에 있는 iterator가 가리키는건, 첫번째의 요소를 그 중간에 있는 이터레이터가 가리키는 곳까지 보내겠다는 것이다. 그래서 그 위치를 iterator로 나타내는데, 

위의 풀이에서는 오른쪽으로 한칸 보내는 경우는 begin()을 begin()+1로 보내고, 왼쪽으로 보내는 것은, begin()을 end()-1의 위치까지 보내겠다는 것이어서 결과적으로 모든 원소들을 왼쪽으로 보낸것과 같은 결과를 출력한다. 

rotate() 함수의 경우는  시퀀스 컨테이너에서 사용할 수 있는 함수라는 것을 기억하고, 다음에 이런 결과물이 필요할때 rotate() 함수를 떠올리고 사용해보도록 하자. 

 

내가 사용한 deque를 이용하는 방식, 그리고 두번재로 소개한 rotate() 함수를 이용하는 방식 말고도, 

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> numbers, string direction) {
    vector<int> answer;
    if(direction == "right"){
        answer.push_back(numbers.back());
        for(int i = 0; i<numbers.size()-1; i++)
            answer.push_back(numbers[i]);
    }
    else{
        for(int i = 1; i < numbers.size(); i++)
            answer.push_back(numbers[i]);
        answer.push_back(numbers.front());
    }

    return answer;
}

이와같이 영역을 나누어서 answer 벡터에 해당 순서에 맞게 원소들을 새롭게 넣어서 만든 배열을 반환하는 형식의 풀이도 가능했다. 

deque의 사용을 생각하지 않았다면 이런식의 접근 또한 괜찮은 접근이 될 것이라고 생각된다. 

 

'알고리즘 > 프로그래머스' 카테고리의 다른 글

Lv 0. 합성수 찾기  (0) 2023.09.21
Lv 0. 주사위의 개수  (0) 2023.09.21
Lv 0. 공 던지기  (0) 2023.09.20
Lv 0. 2차원으로 만들기  (0) 2023.09.20
Lv 0. 점의 위치 구하기  (0) 2023.09.20
  Comments,     Trackbacks