在多集中查找值并擦除(如果存在)

find value in multiset and erase if exists

提问人:Ivan 提问时间:9/24/2022 最后编辑:Ivan 更新时间:9/25/2022 访问量:115

问:

我有这样的代码:

// implementation of multiset
#include <condition_variable> // std::condition_variale
#include <iostream>
#include <iterator>
#include <set>
#include <thread>
#include <algorithm>
#include <mutex>


using namespace std;

class Rect{
public:
        double height;
        double width;
        double area;
        string name;

        friend ostream& operator<<(ostream& os, const Rect& r);
};

ostream& operator<<(ostream& os, const Rect& r)
{
    os << r.area << " " << r.name;
    return os;
}

struct LessArea
{
    bool operator ()(const Rect& lhs, const Rect& rhs) const
    {
        return lhs.area < rhs.area;
    }
};

std::multiset<Rect, LessArea> rects;

我正在生成数据(在线程中,但可能不相关)。在我插入新的之前,我想搜索 如果存在该名称,则为它。然后添加新的:RectmultisetRectdelete

produceData()
{
  const string arrayString[4] = {"C", "B", "N", "A"};
  int RandIndex = rand() % 4; //generates a random number between 0 and 3
  string name = arrayString[RandIndex];

  int randomNumber1 = (int)(rand() % 1000);
  int randomNumber2 = (int)(rand() % 1000);
  int randomNumber3 = (int)(rand() % 1000);

  Rect value = {randomNumber1, randomNumber2, randomNumber3, name};

  // I would like to delete a rect if the name already exists regardless of other values
  rects.erase(s.lower_bound(value)); // This won't work because it is matching ALL fields


  // Add new value
  addToMultiSet(value);
}

如果已经包含,我该如何删除该元素?searchmultisetname

编辑 1

class Rect{
public:
        double height;
        double width;
        double area;
        string name;

        bool operator == ( const Rect & rhs ) const { return ( name == rhs.name ); }
        friend ostream& operator<<(ostream& os, const Rect& r);
};

...

multiset<Rect>::iterator ceItr = rects.find( value );

if(ceItr != rects.end())
{
    rects.erase(ceItr);
}
C++ 算法 搜索 std 多集

评论

2赞 Human-Compiler 9/24/2022
“这需要超快,因为它是一个实时应用程序”——你已经在使用一个,那些并不完全以效率着称。由于所有的指针追逐,您将始终有大量的缓存未命中。只是出于好奇,为什么会这样?如果名称是唯一的,则使用名称作为键更容易删除。如果这很重要,您始终可以有一个单独的数据结构,例如向量,它将迭代器维护到集合中以保持按区域的顺序。迭代器的间接性与遍历范围相同。multisetmultisetsetmultiset
1赞 Sam Varshavchik 9/24/2022
正确。多集总是按其键查找,并按键排序。
1赞 Jesper Juhl 9/24/2022
这当然可以简化为 SSCCE - 它目前不是一个。
1赞 Arnab De 9/24/2022
我不清楚你的要求。当您找到具有相同名称的对象时,您是打算删除它,还是进行更新就足以满足您的目的?此外,您似乎正在与为单个键设计的数据结构作斗争,在您的例子中,该键是对象的面积,并且您希望在对象的字段旁边有一个二级键。我认为您应该探索像 Boost multiindex 这样的东西,看看它是否满足您的需求。RectRectnameRect
1赞 Kenny Ostrom 9/24/2022
您是否需要按名称快速查找并能够遍历按区域排序的矩形?如果您只需要快速查找名称,unsorted_map<name,Rect>?或者你可以同时引用同一个对象,并且为了快速删除,只需在矩形上设置一个标志,告诉它不要打印(稍后清理)?

答: 暂无答案