繁体   English   中英

保留排序序列而没有小于谓词

[英]Keeping sorted sequence without a less-than predicate

我想保持项目的排序队列,在这里我希望能够弹出具有最低值的项目(有点像std::priority_queue )。 项目值是连续的并且不断增加。 但是,这些项没有定义小于比较的谓词,它们仅具有is-previousis-next谓词(其中A is-previous B == B is-next A ),它们还支持++--

我想知道是否有基于此类谓词的(部分)排序值算法? 或者,是否有更好的方法来跟踪此类队列?

在以模算术工作时会出现此问题-项由整数指定,但是由于取模,小于和大于小于它们的含义,并且不能再用于排序。

选择的语言是C ++,但是我想我可以移植大多数合理的语言。

编辑

在尝试编写示例代码时,所有试图回答问题的人都感到惊讶,我意识到最初的问题是不正确的。 这确实很令人尴尬,但我想强调的是,您的时间并没有浪费,因为我花了一个小时流汗,然后在十分钟内,我意识到这是错误的。 无论如何,这是我想要的行为:

template <class T>
class OrderedQueue {
    std::vector<T> storage;
    T next;

public:
    OrderedQueue(T lowest_value = T())
        :next(lowest_value)
    {}

    void Push(T t)
    {
        storage.push_back(t);
    }

    T Pop()
    {
        std::vector<T>::iterator it = std::find(storage.begin(), storage.end(), next);
        if(it == storage.end())
            throw std::runtime_error("no such element");
        T value = *it;
        storage.erase(it);
        ++ next;
        return value;
    }
};

我的问题是Pop()接受O(N) 是否可以使用is-prev和is-next谓词来使其更快?

我的问题是Pop()需要O(N)。 是否可以使用is-prev和is-next谓词来使其更快?

您需要提供一种获取键的实际模块化整数表示形式的方法,例如Integer(x) 然后, PushPop都可以在恒定时间内执行。

如果您有整数和模数M ,请使用一个双向链接列表数组( std::list<T> queues[M] ),将Push(x)queues[Integer(x)].push_back(x)Pop

size_t i = Integer(next);
// check for existence, raise if necessary
T r = queues[i].front();
queues[i].pop_front();
return r;

如果M很大,并且您希望大多数队列在大多数时间都是空的,则可以使用std::unordered_map<size_t, std::list<T>>来获得相同的复杂度,但可以节省空间。

也可以使用std::deque ; 只能为这两种操作提供摊销的固定时间,但实际上可能要快得多。

在C ++中,您的类型不需要定义operator<即可进行排序或在关联容器中使用。 容器和算法可以采用谓词来执行比较。 例如,使用is_pred作为谓词对向量进行排序(假设它已经是一个函数对象或一个普通函数):

std::sort(v.begin(), v.end(), is_pred);

如果没有,您可以编写自己的函子适配器或lambda:

std::sort(v.begin(), v.end(), [](T const& lhs, T const& rhs) {
             return apply_is_pred_predicate(lhs,rhs)
          });

这里的要求是,关系is-prev必须是严格的弱阶。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM