私はこの場合、ポインタを含むいくつかのvector
のコレクションを持っています。ポインタの順序は特にありません。私はベクトルに同じポインタが含まれているかどうかをチェックする方法を考え出しています。これはよい考えですか?等価な比較が高速であるように、ベクトルからのポインタを合計するクラス
私はポインタを整数として解釈し、それらを合計するという考えを思いつきます。 2つのベクトルの和が同じ場合、含まれるポインタは同じでなければなりません。それは良い動作し、私は何の問題も見ていない。しかし、このアイデアが衝突して偽陽性を返す場合があります(実際に異なる場合、同じベクトルを報告する)。
私の質問は、この衝突を乗り切る方法がある場合ですか?
注:ベクトルの並べ替えはオプションではありません。
編集:私は多くのそのようなポインタのベクトルを持つことができました私のアプリケーションで 。そして今、そして1人がコレクションに参加しています(1000個のベクトルかもしれません)。これが起こると、他のベクトルが既に同じ要素をカバーしているかどうかを確認する必要があります。そうであれば、新人は捨てられる。どのポインタベクトルが既にコレクションに入っているかを把握するために、私は今ではstd::set
を使用しています(私の実際のPtrHasher
は、ここに示すより多くの演算子をサポートしています)。従って、一意性をチェックするために必要な操作は、1)すべてのポインタを線形的に合計し、2)一定時間内にセットをチェックする。
私のコメントで書いたように、私のアプリケーションでは、「何らかの」偽陽性(すでにカバーされていなくてもベクターを破棄)を処理できます。したがって、総和は私のために働く。私がこの質問をする理由は、誤検出を最小限に抑えるが、同じ性能を与える他の方法(またはより良い操作)が実際にある場合です。
以前の実装では、 "カバレッジチェック"のためにstd::set
も使用されていましたが、パフォーマンスははるかに悪かったです。ここ
は私のコードである:
#include <iostream>
#include <vector>
#include <stdint.h> // std::uintptr_t
using namespace std;
template<typename T>
class PtrHasher
{
public:
PtrHasher(vector<T> v) : hash(0) {
for(const auto i : v)
add(i);
}
void add(T pointer) {
hash += reinterpret_cast<uintptr_t>(pointer);
}
bool operator ==(const PtrHasher<T>& other) const {
return hash == other.hash;
}
private:
uintptr_t hash;
};
int main() {
vector<int> values{0,1,2,3,4};
vector<int*> ptr1{ &values.at(0), &values.at(2), &values.at(4) }; // points to 0,2,4
vector<int*> ptr2{ &values.at(4), &values.at(0), &values.at(2) }; // points to 4,0,2 i.e. same positions
vector<int*> ptr3{ &values.at(4), &values.at(3), &values.at(2) }; // points to 4,3,2 i.e. not quite the same position
PtrHasher<int*> hasher1(ptr1);
PtrHasher<int*> hasher2(ptr2);
PtrHasher<int*> hasher3(ptr3);
cout<< (hasher1==hasher2) <<endl;
cout<< (hasher1==hasher3) <<endl;
cout<< (hasher2==hasher3) <<endl;
return 0;
}
合計は、整合性チェックまたは重複のチェックには不適切です。 1つのポインタが平均値よりも小さく、1つのポインタが2つ重複するポインタ値を持つのと同じになることがあります。 –
重複が検出されたときに検索を停止する必要がありますか、最後まで待つことができますか?ブール演算を使うと、各スロットで 'if'文を使うよりも効率的です。ほとんどの比較には分岐が含まれているため、処理効率が低下する可能性があります。 –
私はそれをよく知っています - したがって、私の質問です。私のアプリケーションでは、「平均化」のためにいくつかの偽陽性で暮らすことができます。しかし、それほど良いものはありません。私は意図についてコメントするために私の質問を更新しますが、私はそれほど明確ではないと思います。 – dani