如何将平等元素插入Btreemap?

发布于 2025-01-30 11:42:07 字数 3039 浏览 2 评论 0原文

我正在从事一个需要订购的项目,并为此使用Btreeset。 我的btreeset中的元素是pitem它们基本上只是itemdroundedfloat的元组, (item,orderedfloat< f64>)) - >像struct Pitem(项目,重量)一样阅读 现在棘手的部分:我的btreemap应该仅根据重量订购pitems,而无视项目。 如果我的btreemap已经包含一个pitem,则仅应由该项目确定,而无视重量。这是我对ord and eq的实现和pitem的实现:

use ordered_float::OrderedFloat;
use std::cmp::Ordering;

#[derive(Eq)]
pub struct Item{
    pub s_i: u32,
    pub e_i: u32,
    pub val: String,
}
#[derive(Eq)]
pub struct PItem(pub Item, pub OrderedFloat<f64>);

impl Item{
    pub fn start(&self) -> u32{
        self.s_i
    }
    pub fn end(&self) -> u32{
        self.e_i
    }

    pub fn val(&self) -> &str{
        &self.val
    }
}

impl PItem{
    pub fn start(&self) -> u32{
        self.item().start()
    }
    pub fn end(&self) -> u32{
        self.item().end()
    }
    pub fn prob(&self) -> &OrderedFloat<f64>{
        &(self.1)
    }
    pub fn val(&self) -> &str{
        self.item().val()
    }
    pub fn item(&self) -> &Item{
        return &self.0
    }
}

impl PartialOrd for Item {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.s_i == other.s_i{
            if self.e_i == other.e_i{
                return self.val.partial_cmp(&(other.val));
            }
            return self.e_i.partial_cmp(&(other.e_i));        
        }
        return self.s_i.partial_cmp(&(other.s_i));
    }
}

impl PartialEq for Item {
    fn eq(&self, other: &Self) -> bool {
        self.s_i.eq(&(other.s_i)) && self.e_i.eq(&(other.e_i)) && self.val.eq(&(other.val))
    }
}

impl Ord for PItem {
    fn cmp(&self, other: &PItem) -> Ordering {
        if self.prob() == other.prob(){
            return self.item().cmp(&(other.item()));       
        }
        return self.prob().cmp(&(other.prob()));
    }
}


impl PartialOrd for PItem {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.prob() == other.prob(){
            return self.item().partial_cmp(&(other.item()));        
        }
        return self.prob().partial_cmp(&(other.prob()));
    }
}

impl PartialEq for PItem {
    fn eq(&self, other: &Self) -> bool {
        self.item().eq(&(other.item()))
    }
}

impl Ord for Item {
    fn cmp(&self, other: &Item) -> Ordering {
        if self.start() == other.start(){
            if self.end() == other.end(){
                return self.val().cmp(&(other.val()));
            }
            return self.end().cmp(&(other.end()));        
        }
        return self.start().cmp(&(other.start()));
    }
}

但是,我看到,当它们具有不同的权重时,我可以在btreemap中两次添加“相同” pitem。当一切都相等,包括重量时,我无法插入它。

我想要的是,即使权重不同,我也无法插入它,但是item的s是相等的。因此,显然,在确定集合中是否已经存在项目时,它会考虑到重量。这是为什么?我在代码中找不到错误。当我仅检查不添加任何PITEM的平等时,EQ方法似乎正常。

I am working on a project where I need an Ordered Set and I use a BTreeSet for that.
The Elements in my BTreeSet are PItem they are basically just a tuple of an Item and an OrderedFloat, like this: struct PItem((Item, OrderedFloat<f64>)) -> read like struct PItem(Item, weight)
Now the tricky part: My BTreeMap should order the PItems only based on the weight, disregarding the Item.
If my BTreeMap already contains an PItem on the other hand should only be determined by the Item, disregarding the weight. Here is my Implementation for Ord and Eq for Item and PItem:

use ordered_float::OrderedFloat;
use std::cmp::Ordering;

#[derive(Eq)]
pub struct Item{
    pub s_i: u32,
    pub e_i: u32,
    pub val: String,
}
#[derive(Eq)]
pub struct PItem(pub Item, pub OrderedFloat<f64>);

impl Item{
    pub fn start(&self) -> u32{
        self.s_i
    }
    pub fn end(&self) -> u32{
        self.e_i
    }

    pub fn val(&self) -> &str{
        &self.val
    }
}

impl PItem{
    pub fn start(&self) -> u32{
        self.item().start()
    }
    pub fn end(&self) -> u32{
        self.item().end()
    }
    pub fn prob(&self) -> &OrderedFloat<f64>{
        &(self.1)
    }
    pub fn val(&self) -> &str{
        self.item().val()
    }
    pub fn item(&self) -> &Item{
        return &self.0
    }
}

impl PartialOrd for Item {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.s_i == other.s_i{
            if self.e_i == other.e_i{
                return self.val.partial_cmp(&(other.val));
            }
            return self.e_i.partial_cmp(&(other.e_i));        
        }
        return self.s_i.partial_cmp(&(other.s_i));
    }
}

impl PartialEq for Item {
    fn eq(&self, other: &Self) -> bool {
        self.s_i.eq(&(other.s_i)) && self.e_i.eq(&(other.e_i)) && self.val.eq(&(other.val))
    }
}

impl Ord for PItem {
    fn cmp(&self, other: &PItem) -> Ordering {
        if self.prob() == other.prob(){
            return self.item().cmp(&(other.item()));       
        }
        return self.prob().cmp(&(other.prob()));
    }
}


impl PartialOrd for PItem {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.prob() == other.prob(){
            return self.item().partial_cmp(&(other.item()));        
        }
        return self.prob().partial_cmp(&(other.prob()));
    }
}

impl PartialEq for PItem {
    fn eq(&self, other: &Self) -> bool {
        self.item().eq(&(other.item()))
    }
}

impl Ord for Item {
    fn cmp(&self, other: &Item) -> Ordering {
        if self.start() == other.start(){
            if self.end() == other.end(){
                return self.val().cmp(&(other.val()));
            }
            return self.end().cmp(&(other.end()));        
        }
        return self.start().cmp(&(other.start()));
    }
}

Now however, I see that I can add the "same" PItem twice to the BTreeMap, when they have different weights. When everything is equal including the weight, I cannot insert it.

What I want is that I already cannot insert it even if the weight is different but the Item's are equal. So apparently it takes the weight into consideration when deciding if an Item is already present in the set. Why is that? I cannot find my mistake in the code. When I check only for equality without adding any PItem to some set, the eq method seems to work fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文