developer tip

std :: queue 반복

optionbox 2020. 11. 18. 08:56
반응형

std :: queue 반복


반복해야합니다 std::queue. www.cplusplus.com 말한다 :

기본적으로 특정 대기열 클래스에 대해 지정된 컨테이너 클래스가 없으면 표준 컨테이너 클래스 템플릿 deque가 사용됩니다.

그래서 어떻게 든 큐의 기본 deque에 도달하여 반복 할 수 있습니까?


반복해야하는 경우 queue대기열 이상의 것이 필요합니다. 표준 컨테이너 어댑터의 요점은 최소한의 인터페이스를 제공하는 것입니다. 반복도 수행해야한다면 데크 (또는 목록)를 대신 사용하지 않는 이유는 무엇입니까?


반복 가능한 컨테이너를 직접 사용하는 것이 선호되는 솔루션이라는 다른 사람들의 의견에 동의하지만 C ++ 표준은 어떤 이유로 든 원하는 경우 자체 솔루션에 대한 충분한 지원을 보장한다는 점을 지적하고 싶습니다.

즉, std::queue보호 된 멤버 에서 상속하고 이를 사용 Container c;하여 기본 컨테이너의 begin () 및 end ()에 액세스 할 수 있습니다 (해당 메서드가 존재하는 경우). 다음은 VS 2010에서 작동 하고 ideone으로 테스트 한 예입니다 .

#include <queue>
#include <deque>
#include <iostream>

template<typename T, typename Container=std::deque<T> >
class iterable_queue : public std::queue<T,Container>
{
public:
    typedef typename Container::iterator iterator;
    typedef typename Container::const_iterator const_iterator;

    iterator begin() { return this->c.begin(); }
    iterator end() { return this->c.end(); }
    const_iterator begin() const { return this->c.begin(); }
    const_iterator end() const { return this->c.end(); }
};

int main() {
    iterable_queue<int> int_queue;
    for(int i=0; i<10; ++i)
        int_queue.push(i);
    for(auto it=int_queue.begin(); it!=int_queue.end();++it)
        std::cout << *it << "\n";
    return 0;
}

원래 대기열을 임시 대기열에 저장할 수 있습니다. 그런 다음 임시 대기열에서 일반 팝을 수행하여 원래 대기열을 통과합니다. 예를 들면 다음과 같습니다.

queue tmp_q = original_q; //copy the original queue to the temporary queue

while (!tmp_q.empty())
{
    q_element = tmp_q.front();
    std::cout << q_element <<"\n";
    tmp_q.pop();
} 

마지막에 tmp_q는 비어 있지만 원래 큐는 변경되지 않습니다.


반복하려는 대기열의 복사본을 만들고 한 번에 하나씩 항목을 제거하여 이동하면서 인쇄하는 것이 어떻습니까? 반복 할 때 요소로 더 많은 작업을 수행하려면 큐가 잘못된 데이터 구조입니다.


반면 알렉세이 Kukanov의 답변이 더 효율적일 수 있습니다, 당신은 또한 매우 자연스러운 방식으로 큐를 통해, 뒤쪽으로 밀어 다음, 대기열의 전면에서 각 요소를 보여주고으로 반복 할 수있다

#include <iostream>
#include <queue>

using namespace std;

int main() {
    //populate queue
    queue<int> q;
    for (int i = 0; i < 10; ++i) q.push(i);

    // iterate through queue
    for (size_t i = 0; i < q.size(); ++i) {
        int elem = std::move(q.front());
        q.pop();
        elem *= elem;
        q.push(std::move(elem));
    }

    //print queue
    while (!q.empty()) {
        cout << q.front() << ' ';
        q.pop();
    }
}

산출:

0 1 4 9 16 25 36 49 64 81 

큐를 반복해야하는 경우 큐는 필요한 컨테이너가 아닙니다.
대기열을 선택한 이유는 무엇입니까?
반복 할 수있는 컨테이너를 가져가는 것이 어떻습니까?


1. 대기열을 선택하면 컨테이너를 '대기열'인터페이스로 감싸고 싶다고 말합니다.-전면-후면-푸시-팝-...

반복하려는 경우 대기열에 잘못된 인터페이스가 있습니다. 대기열은 원래 컨테이너의 제한된 하위 집합을 제공하는 어댑터입니다.

2. 큐의 정의는 FIFO이며 정의에 따라 FIFO는 반복 할 수 없습니다.


나는 이와 같은 것을 사용합니다. 매우 정교하지는 않지만 작동합니다.

    queue<int> tem; 

    while(!q1.empty()) // q1 is your initial queue. 
    {
        int u = q1.front(); 

        // do what you need to do with this value.  

        q1.pop(); 
        tem.push(u); 
    }


    while(!tem.empty())
    {
        int u = tem.front(); 
        tem.pop(); 
        q1.push(u); // putting it back in our original queue. 
    }

It will work because when you pop something from q1, and push it into tem, it becomes the first element of tem. So, in the end tem becomes a replica of q1.


In short: No.

There is a hack, use vector as underlaid container, so queue::front will return valid reference, convert it to pointer an iterate until <= queue::back


std::queue is a container adaptor, and you can specify the container used (it defaults to use a deque). If you need functionality beyond that in the adaptor then just use a deque or another container directly.

참고URL : https://stackoverflow.com/questions/1259099/stdqueue-iteration

반응형