2

更新

有一个逻辑,其中整数之前被排入向量中的队列,搜索队列循环并将整数排入队列中具有最小大小的队列。下面的代码展示了操作

#include <vector> 
#include <queue> 
std::vector<std::queue<int> > q
int min_index = 0;
std::size_t size = q.size();
for( i=0; i<size; i++){ //accessing loop of queues
    if(q[min_index].size() > q[i].size())
        min_index = i; // Now q[min_index] is the shortest queue
} 
q[min_index].push(int)

我正在尝试扩展这个逻辑,条件是整数应该继续在最短队列中排队,而条件为真的最短队列的大小小于或等于队列循环中任何另一个队列的大小。

我想做如下所示的代码

#include <vector> 
    #include <queue> 
    std::vector<std::queue<int> > q
    int min_index = 0;
    std::size_t size = q.size();
    for( i=0; i<size; i++){ //accessing loop of queues
        if(q[min_index].size() > q[i].size())
            min_index = i

    while(q[min_index].size <= q[some_other_index].size() )
    {
        q[min_index].push(int);

}

如何实现这个逻辑?

4

1 回答 1

3

最干净的解决方案需要 C++11:

std::min_element( 
        q.begin(),
        q.end(),
        []( std::queue<int> const& lhs, std::queue<int> const& rhs)
            { return lhs.size() < rhs.size(); } )
    ->push(value);

即使没有 C++11,我想我也会写一个小的谓词类来做 lambda 所做的事情,并使用它。

编辑:

现在我对想要什么有了更好的了解,下面的内容应该可以解决问题:

class OrderInMap
{
    MultiQueue* myOwner;
public:
    OrderInMap( MultiQueue* owner )
        : myOwner( owner )
    {
    }
    bool operator()( int lhs, int rhs ) const
    {
        return myOwner->myQueues[ lhs ].size()
                < myOwner->myQueues[ rhs ].size();
    }
};

std::vector <std::queue<int>> myQueues;
std::vector <int> myMap;
int myCurrent;
bool myOrderIsValid;
OrderInMap myOrder;

int getIndexForPush()
{
    if ( ! myOrderIsValid || myOrder( myMap[0], myCurrent ) ) {
        myMap.push_back( myCurrent );
        std::push_heap( myMap.begin(), myMap.end(), myOrder );
        std::pop_heap( myMap.begin(), myMap.end(), myOrder );
        myCurrent = myMap.back();
        myMap.pop_back();
    }
    return myCurrent;
}

由于弹出可以更改顺序,因此您必须 myOrderIsValid在弹出时设置为 false (或者可能仅在弹出之后,myOrder( poppedIndex, myMap.front() ))。

或者,您可以手动完成,并避免使用地图(但您必须保留两个变量):

int myCurrent;
int myNext;

void order()
{
    if ( myQueues[myNext].size() < myQueues[myCurrent].size() ) {
        std::swap( myNext, myCurrent );
    }
}
int getQueueIndex()
{
    if ( ! myOrderIsValid || myQueues[myNext].size() < myQueues[myCurrent].size() ) {
        myCurrent = 0;
        myNext = 1;
        order();
        for ( int i = 2; i < myQueues.size(); ++ i ) {
            if ( myQueues[i].size() < myQueues[myNext].size() ) {
                myNext = i;
                order();
            }
        }
    }
    return myCurrent;
}

这可能比维护堆要慢,但即使有大量队列,我也不确定差异是否明显。

于 2013-02-15T12:43:16.967 回答