有没有一种有效的方法来比较两个执行 STL 类型操作的向量,这样我就不必对它们进行排序或复制它们?问题是排序导致我必须在 getIntersection 方法上创建一个锁,理想情况下我想避免这种情况,因为它实际上只是读取数据结构并在其中查找数据而不是更改它。sort 方法改变了数据结构,因此该方法的其他调用需要同步。我可能只需要创建一个副本,但这可能是一个大副本,但可能比锁定更快,但不确定。因此我的问题变成了搜索排序的向量是否比仅仅获取锁或副本的价格更有效。考虑以下示例:
class X
{
public:
struct TestX
{
long id;
.......... // other items
};
void getIntersectionByID ( vector<TextX>& result, const vector<TestX>& ids)
{
return getItemsByIntersection<long,TestX>( result, _v1, ids, &TestX::id);
return false;
}
private:
vector<TestX> _v1; // assume this is populated with data
};
// generic pred to do weak ordering on a structure by a generic field
// this is a generalized less than function which can be used for ordering
// and other equality operations
template<typename T, typename K>
struct byField
{
public:
byField(T K::* idMember) : idMember_(idMember) {}
bool operator() (const K& obj1, const K& obj2)
{
return ( obj1.*idMember_ < obj2.*idMember_ );
}
private:
T K::* idMember_;
};
template <typename T, typename K>
bool getItemsByIntersection ( std::vector<K>& retds, std::vector<K>& ds, const std::vector<T>& values, T K::* field )
{
//create the vector of structs to use for comparison
typename std::vector<K> searchCriteria(values.size());
typename std::vector<K>::iterator itS = searchCriteria.begin();
// assign the item to the vector
for (typename std::vector<T>::const_iterator it = values.begin(), itEnd = values.end(); it != itEnd; ++it,++itS)
{
(*itS).*field = *it;
}
// reserve half the size of the total ds just to be safe
typename std::vector<K> tmp;
tmp.reserve(ds.size()/2);
sort( ds.begin(), ds.end(), byField<T,K>(field) );
sort( searchCriteria.begin(), searchCriteria.end(), byField<T,K>(field) );
setGrep ( ds.begin(), ds.end(), searchCriteria.begin(), searchCriteria.end(), std::back_inserter(tmp), byField<T,K>(field) );
// don't change state until the very end, any existing contents in retds are destroyed
retds.swap(tmp);
if ( !retds.empty() )
{
return true;
}
return false;
}
/ this is a set grep meaning any items that are in set one
// will be pulled out if they match anything in set 2 based on operator pred
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
_OutputIterator
setGrep(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
_OutputIterator __result, _Compare __comp)
{
while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first1, *__first2))
++__first1;
else if (__comp(*__first2, *__first1))
++__first2;
else
{
*__result = *__first1;
++__first1;
++__result;
}
return __result;
}