在 c++ 优先级队列中,我是不是需要在修改其属性后再次重新推送对象?

Posted

技术标签:

【中文标题】在 c++ 优先级队列中,我是不是需要在修改其属性后再次重新推送对象?【英文标题】:In c++ priority queue, do I need to re push an object again after modifying its properties?在 c++ 优先级队列中,我是否需要在修改其属性后再次重新推送对象? 【发布时间】:2021-07-08 13:27:25 【问题描述】:

我提供的是分数背包问题的解决方案的完整代码。在代码的最后我会解释问题,

#include<iostream>
#include<queue>

#define MAX_WEIGHT 5

using namespace std;

class Item
public:
    int weight;
    int benefit;
    float weightPerBenefit;
    int selectedWeight = 0;

    Item(int weight, int benefit)
        this->weight = weight;
        this->benefit = benefit;
        this->weightPerBenefit = (float)this->weight/(float)this->benefit;
    

    void setSelectedWeight(int w)
        this->selectedWeight = w;
    

    bool operator < (const Item &item) const
        return weightPerBenefit < item.weightPerBenefit;
    
;

void displayItems(priority_queue<Item> items)
    while(!items.empty())
        Item item = items.top();
        items.pop();
        cout << "Item Benefit: " << item.benefit << ", Selected Weight: " << item.selectedWeight << endl;;
    


void fractionalKnapsack(priority_queue<Item> items)
    int rw = MAX_WEIGHT;
    while(!items.empty())
        Item item = items.top();
        items.pop();
        int w = item.weight;
        if(w > rw)
            item.setSelectedWeight(rw);
            break;
        
        else
            //cout << w << endl;
            item.setSelectedWeight(w);
            rw = rw-w;
        
    


int main()

    int size;
    cout << "Enter total number of items: ";
    cin >> size;
    priority_queue<Item> items;

    int data[size][2];
    for(int i=0; i<size; i++)
        cout << "Enter item weight: ";
        cin >> data[i][0];
        cout << "Enter item benefit: ";
        cin >> data[i][1];
        cout << endl;
    
    for(int i=0; i<size; i++)
        Item item(data[i][0], data[i][1]);
        items.push(item);
    

    //displayItems(items);
    fractionalKnapsack(items);
    displayItems(items);


所以,问题是每当调用fractionalKnapsack 函数并更新对象的属性时,在显示方法之后它会显示在开始时定义的属性值0。它不会更新为新值。

我对priority_queue不太了解,必须使用优先队列来完成。我不知道为什么会发生这个错误。

【问题讨论】:

fractionalKnapsack 清空队列的副本,保持原件不变。而且无论如何也无法修改priority_queue 中的元素。 另外,贪心算法是“尽可能多地取‘最好’的项目,然后是第二好的,以此类推”。这不需要对元素进行任何修改 - 只需弹出它们直到你的背包装满或用完东西。 当您决定将结果存储在与输入相同的位置时,我认为您走错了方向。 【参考方案1】:

参考:http://www.cplusplus.com/reference/queue/priority_queue/top/

std::priority_queue::top 返回对priority_queue 中顶部元素的常量引用。

Item item = items.top();
items.pop();
item.setSelectedWeight(rw);

在那里,您只需创建一个局部变量并使用它。我认为应该重新插入它。

PS:对于一些 STL get 方法。如果更改它的值是安全的,它将返回一个引用,否则返回 const 引用。

【讨论】:

以上是关于在 c++ 优先级队列中,我是不是需要在修改其属性后再次重新推送对象?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要在 C++ 中使用不同的排序格式来对这个 USACO 代码上的数组和优先级队列进行排序?

如何在 C++ 中正确使用优先级队列

为啥在c++中实现基于类的优先级队列时需要重载operator<?

带链表的 C++ 优先级队列类

在 C++ 中分配真或假的随机对象

(c++)迷宫自动寻路-队列-广度优先算法-附带寻路打印动画