Вставьте в очередь STL, использующую станд.:: копия

Это довольно простая работа, и awk - действительно нужный инструмент:

awk 'NR==FNR{a[$1]=$2;next}{print [110],a[$1]}' fileb filea

или

awk 'NR==FNR{a[$1]=$2;next}{print $1,$2,a[$1]}' fileb filea

Но, пожалуйста, покажите свои собственные усилия в следующий раз, как Вы искали / пытались и не смогли.
Помоги себе, помоги другим помочь тебе.

16
задан 眠りネロク 4 May 2018 в 20:08
поделиться

8 ответов

К сожалению std :: queue «адаптирует» функцию, известную как push_back , только для push , что означает, что стандартный back_insert_iterator не работает.

Вероятно, самый простой способ (хотя концептуально уродливый) - это адаптировать адаптер контейнера с короткоживущим адаптером адаптера контейнера [sic] (эй!), Который живет до тех пор, пока не будет вставить итератор.

template<class T>
class QueueAdapter
{
public:
    QueueAdapter(std::queue<T>& q) : _q(q) {}
    void push_back(const T& t) { _q.push(t); }

private:
    std::queue<T>& _q;
};

Используется так:

std::queue<int> qi;

QueueAdapter< std::queue<int> > qiqa( qi );

std::copy( v.begin(), v.end(), std::back_inserter( qiqa ) );
21
ответ дан 30 November 2019 в 16:19
поделиться

Я почти уверен, что это просто не сработает - очередь предоставляет push, но итератор вставки предполагает использовать push_front или push_back. Нет никакой реальной причины, по которой вы не могли бы написать свое push_insert_iterator (или любое другое имя, которое вы предпочитаете), но это немного болезненно ...

3
ответ дан 30 November 2019 в 16:19
поделиться

insert_iterator и back_insert_iterator работают только с контейнерами (или адаптерами) с (соответственно) методами insert и push_back - очередь их не имеет. Вы можете написать свой собственный итератор, смоделированный на их основе, примерно так:

template <typename Container> 
class push_iterator : public iterator<output_iterator_tag,void,void,void,void>
{
public:
    explicit push_iterator(Container &c) : container(c) {}

    push_iterator &operator*() {return *this;}
    push_iterator &operator++() {return *this;}
    push_iterator &operator++(int) {return *this;}

    push_iterator &operator=(typename Container::const_reference value)
    {
         container.push(value);
         return *this;
    }
private:
    Container &container;
};

Если такая вещь еще не существует, но я почти уверен, что это не так.

3
ответ дан 30 November 2019 в 16:19
поделиться

std :: queue не контейнер в смысле STL, это контейнер адаптер с очень ограниченной функциональностью. Для того, что вам, кажется, нужно, либо std :: vector , либо std :: deque («двусторонняя очередь, которая является« настоящим контейнером ») кажется правильным выбором.

3
ответ дан 30 November 2019 в 16:19
поделиться

Очередь не допускает итерацию по своим элементам.

Из SGI STL Docs :

Очередь - это адаптер, который предоставляет ограниченное подмножество контейнера функциональность Очередь - это "первый в структура данных «первым вышел» (FIFO). 1 То есть элементы добавляются в в конце очереди и может быть удален спереди; Q.front () - это элемент, который был добавлен в очередь по крайней мере недавно. Очередь не позволяет итерация по его элементам. [2]

Вы можете выполнить эту работу, но вы не можете использовать insert_iterator . Вам нужно будет написать что-то вроде queue_inserter , представляющее интерфейс итератора.

Обновление Я не мог с собой поделать и решил попробовать реализовать нужный итератор. Вот результаты:

template< typename T, typename U >
class queue_inserter {
    queue<T, U> &qu;  
public:
    queue_inserter(queue<T,U> &q) : qu(q) { }
    queue_inserter<T,U> operator ++ (int) { return *this; }
    queue_inserter<T,U> operator * () { return *this; }
    void operator = (const T &val) { qu.push(val); }
};

template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q) {
    return queue_inserter<T,U>(q);
}    

Это отлично работает для таких функций:

template<typename II, typename OI>
void mycopy(II b, II e, OI oi) {
    while (b != e) { *oi++ = *b++; }
}

Но это не работает с копией STL, потому что STL глуп.

8
ответ дан 30 November 2019 в 16:19
поделиться

Что вам нужно, так это push_inserter (то есть устройство вставки, которое выполняет push es в очередь). Насколько мне известно, такого итератора в STL нет. Что я обычно делаю, так это, к сожалению, возвращаюсь к старому доброму циклу for.

Если у вас хватит смелости, вы можете создать свой собственный итератор, что-нибудь в этом роде:

template <typename Container>
class push_insert_iterator
{
  public:
    typedef Container                      container_type;
    typedef typename Container::value_type value_type;

    explicit push_insert_iterator(container_type & c)
        : container(c)
    {}    // construct with container

    push_insert_iterator<container_type> & operator=(const value_type & v)
    {
        //push value into the queue
        container.push(v);
        return (*this);
    }

    push_insert_iterator<container_type> & operator*()
    {
        return (*this);
    }

    push_insert_iterator<container_type> & operator++()
    {
        // Do nothing
        return (*this);
    }

    push_insert_iterator<container_type> operator++(int)
    {
        // Do nothing
        return (*this);
    }

  protected:
    container_type & container;    // reference to container
};

template <typename Container>
inline push_insert_iterator<Container> push_inserter(Container & c)
{
    return push_insert_iterator<Container>(c);
}

Это всего лишь черновик, но идея у вас есть. Работает с любым контейнером (или, ну, контейнерными адаптерами) с методом push (например, queue , stack ).

2
ответ дан 30 November 2019 в 16:19
поделиться

std :: queue не является одним из основных контейнеров в STL. Это контейнерный адаптер, созданный с использованием одного из базовых контейнеров STL (в данном случае одного из последовательных контейнеров либо std :: vector std :: deque , либо std :: list ). Он разработан специально для поведения FIFO и не обеспечивает случайную вставку в заданный итератор, который требуется для работы insert_iterator . Следовательно, будет невозможно использовать такую ​​очередь.

Самый простой способ, который я мог придумать, - это:

class PushFunctor
{
public:
    PushFunctor(std::queue<int>& q) : myQ(q)
    {
    }
    void operator()(int n)
    {
        myQ.push(n);
    }

private:
    std::queue<int>& myQ;
};

И использовать его так:

queue<int> q;
PushFunctor p(q);
std::for_each(v.begin(), v.end(), p);
1
ответ дан 30 November 2019 в 16:19
поделиться

In this simple case, you can write:

vector<int> v;
v.push_back( 1 );
v.push_back( 2 );

queue<int, vector<int> > q(v);

This will make a copy of the vector and use it as the underlying container of the queue.

Of course, this approach won't work if you need to enqueue things after the queue has been constructed.

0
ответ дан 30 November 2019 в 16:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: