我有一个名为Neighbors
的类型:
typedef vector<pair<data,int>> Neighbors;
以及data
:
struct data
{
int par[PARAMETERS];
int cluster;
bool visited;
bool noise;
};
我试图编写一个函数,将_NeighborPts
的值插入NeighborPts
(但只有NeighborPts
中已有的值):
void insert_unique(Neighbors* NeighborPts, const Neighbors& _NeighborPts)
{
Neighbors_const_it _it = _NeighborPts.begin();
while(_it != _NeighborPts.end())
{
if(/* _it->first.par isn't in *NeighborPts */)
NeighborPts->push_back(*_it);
++_it;
}
}
我已经有一个函数equal()
来检查2 par
是否相等。
所以我必须在while循环中迭代NeighborPts
并检查是否找到了该项目?或者我可以使用一些内置的find
或find_if
函数为我做这个吗?
答案 0 :(得分:1)
您可以维护已排序的矢量。使用C ++算法中的lower_bound
函数每次都能找到插入位置。如果插入位置的元素等于insert元素,那么你有一个副本。
除非矢量变得太大,否则性能将非常好。您使用套装或无序套装更好的地方会有所不同,您需要通过基准测试才能找到它。
答案 1 :(得分:0)
你当前使用vector的解决方案将在O(N ^ 2)时间运行,这是无效的。 对于有效的解决方案,关联容器会很棒 - 例如std :: set。 你还需要一些&#34;较少的操作员&#34; (而不是&#34; equal()&#34;),传递给函数。
template < class T, // set::key_type/value_type
class Compare = less<T>, // set::key_compare/value_compare
class Alloc = allocator<T> // set::allocator_type
> class set;
所以你需要提供比较类
struct data_compare {
bool operator() (const data& lhs, const data& rhs) const{
//...
}
};
set<int64_t, data_compare> exising_items;
您可以定义这样的功能,或覆盖&#34;运算符&lt;&#34;在struct data。
插入所有&#34;数据&#34;来自&#34; _NeighborPts&#34;进入集合 - O(N * log(N))时间
std :: set other_items; 在循环中 - 迭代_NeighborPts并插入数据元素
other_items.insert (_NeighborPts [i]);
std :: set my_items; 在循环中 - 迭代_NeighborPts并插入数据元素
my_items.insert (NeighborPts [i]);
现在你需要比较两组: 你可以使用std::set_intersection来做 。或者在集合上构建一个简单的循环&#34; my_items&#34; 如果other_items中的当前元素不在_my_items中,请将其插入&#34; NeighborPts&#34;
此解决方案将在 O(Nlog(N))时间
运行答案 2 :(得分:0)
_NeighborPts
中的项目进行迭代。std::vector
,就无法检查项目是否在NeighborPts
之前插入其中。您可以使用std::for_each
和仿函数让代码更容易阅读。
struct UniqueItemInserter
{
UniqueItemInserter(Neighbors* neighborsIn) : neighbors(neighborsIn) {}
void operator(pair<data,int> const& item)
{
if ( std::find(neighbors->begin(), neighbors->end(), item) != neighbors->end() )
{
neighbors->push_back(item);
}
}
Neighbors* neighbors;
};
void insert_unique(Neighbors* NeighborPts, const Neighbors& _NeighborPts)
{
std::for_each(_NeighborPts.begin(), _NeighborPts.end(), UniqueItemInserter(NeighborPts));
}