【问题标题】:comparing queue sizes in a vector比较向量中的队列大小
【发布时间】:2013-02-15 12:21:52
【问题描述】:

更新

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

#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);

}

如何实现这个逻辑?

【问题讨论】:

  • while 循环中再次检查最短队列?
  • @joachim pileborgInside while 循环最短队列大小将与向量中存在的所有其他队列大小进行比较。如果最短队列大小小于或等于队列循环中的任何其他队列大小,它将推送整数。否则它将退出循环
  • @billa 根据定义,最短队列大小将小于或等于任何其他队列大小。否则,它不是最短的。
  • @JamesKanze 没错,我想说“虽然最短队列大小小于或等于队列循环中的任何其他队列大小,但它将推送整数”
  • @billa 你应该更新问题。现在它说“直到”,但你只是说“当”。另外:你能对队列的向量进行排序吗?当你填满最短的队列时会发生什么 - 它完成了还是你选择另一个队列并重新开始?这是否发生在函数内部,如果是,您如何调用该函数?推动的元素来自哪里?等等...您可以分享很多信息来帮助人们回答问题。

标签: c++ loops vector queue


【解决方案1】:

最干净的解决方案需要 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 弹出时为假(或者可能仅在之后 流行音乐,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;
}

这可能比维护堆慢,但即使 非常多的队列,我不确定差异会不会 引人注目。

【讨论】:

  • 您已经算法化/修复了第一个代码 sn-p。我认为提问者 想要 是某种优化以避免为每个 push 操作扫描整个 q - 也就是说,评论中的“任何其他队列大小”的数量在第二个代码中,sn-p 应该被缓存。我可能错了
  • @SteveJessop 也许吧。他一直在说最短队列大小小于或等于其他大小,这并没有告诉我任何事情。如果目标是避免每次都进行搜索,一个解决方案是使用std::vector&lt;int&gt; 来映射索引,并在第二个条目小于第一个条目时使用std::partial_sort。但是手动循环寻找两个最小的并行可能会更快(并且应该不会太难实现)。
  • @JamesKanze我已经更新了这个问题,我很抱歉我错了直到,而不是 while
  • @JamesKanze我认为我们应该找到两个连续的最小值并进行比较?我应该把它作为新问题发布吗?
  • @billa 如果是这种情况,您可以尝试使用std::partial_sort 或堆管理功能来维护地图。
猜你喜欢
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
相关资源
最近更新 更多