请注意equal function。如果我们的目标是勾选similar 足够多的点,我们应该使用为similar 点提供相同散列值的散列和将similar points 分组为相同的approximate-equal。就我而言,我使用以下内容:
# include <iostream>
# include <vector>
# include <unordered_set>
# include <utility>
# include <Eigen/Dense>
const std::string red("\033[0;31m");
const std::string green("\033[1;32m");
const std::string yellow("\033[1;33m");
const std::string cyan("\033[0;36m");
const std::string magenta("\033[0;35m");
const std::string reset("\033[0m");
struct ApproxHash
{
std::size_t operator() (Eigen::Vector2d const& pt) const
{
size_t score = (size_t)(pt.x()*100) + (size_t)(pt.y()*10);
std::cerr <<"Point: "<< pt.transpose()<< " has score: "<<score<<std::endl;
return score;
}
};
struct ApproxEqual{
// This is used to guarantee that no duplicates should happen when the hash collision happens.
public:
bool operator()(const Eigen::Vector2d & pt1, const Eigen::Vector2d & pt2) const {
double threshold = 0.00001;
bool xdiff = fabs(pt1.x() - pt2.x())<threshold;
bool ydiff = fabs(pt1.y() - pt2.y())<threshold;
bool result = (fabs(pt1.x() - pt2.x())<threshold) && (fabs(pt1.y() - pt2.y())<threshold);
std::cerr<<cyan<<"Equal is called for: "<< pt1.transpose()<<" and "<<pt2.transpose()<<" which are " << result<<" equal. "<<" xdiff"<< xdiff<<", ydiff"<<ydiff<<reset<<std::endl;
return result;
}
};
void removeDuplicates(std::vector<Eigen::Vector2d>& vec)
{
// If we would like to store values, we should use std::unordered_map.
std::unordered_set<Eigen::Vector2d, ApproxHash, ApproxEqual> pointset;
auto ii = vec.begin();
while (ii != vec.end())
{
std::cerr<<"Processing: "<<ii->transpose()<<std::endl;
if (pointset.find(*ii) != pointset.end()) // O(1) lookup time for unordered_set
{
std::cerr<<red<<"Found duplicate: "<<ii->transpose()<<reset<<std::endl;
vec.erase(ii); // vec.erase returns the next valid iterator
}
else
{
pointset.insert(*ii);
std::cerr<<"Inserted: "<<ii->transpose()<<std::endl;
ii++;
}
}
} // end of removeDuplicates
int main(int argc, char* argv[])
{
std::vector<Eigen::Vector2d> pointTemp;
pointTemp.resize(15);
pointTemp[0]=Eigen::Vector2d(1.0011121213,1);
pointTemp[1]=Eigen::Vector2d(2.0,3.121);
pointTemp[2]=Eigen::Vector2d(4.004,1.0);
pointTemp[3]=Eigen::Vector2d(2.0,3.121);
pointTemp[4]=Eigen::Vector2d(1.001112121,1);
pointTemp[5]=Eigen::Vector2d(4.004,1.0);
pointTemp[6]=Eigen::Vector2d(1.2,1);
pointTemp[7]=Eigen::Vector2d(0.028297902, 0.302034);
pointTemp[8]=Eigen::Vector2d(0.028297901, 0.302034);
pointTemp[9]=Eigen::Vector2d(0.249941, 0.227669);
pointTemp[10]=Eigen::Vector2d(0.249941, 0.227669);
pointTemp[11]=Eigen::Vector2d(0.0206403, 0.304258);
pointTemp[12]=Eigen::Vector2d(0.0206403, 0.304258);
pointTemp[13]=Eigen::Vector2d(0.0206403, 0.304258);
pointTemp[14]=Eigen::Vector2d(0.0282979, 0.302034);
for (auto & point:pointTemp)
{
std::cout<<point.x()<<", "<< point.y()<<std::endl;
}
removeDuplicates(pointTemp);
std::cerr<<green<<"Cleaned vector: "<<reset<<std::endl;
for (auto & point:pointTemp)
{
std::cout<<point.x()<<", "<< point.y()<<std::endl;
}
return 0;
}
我们可以使用g++ -std=c++11 -I /usr/include vectorHash.cpp -o vectorHash 来编译示例。
如果我们使用exact equal 或exact hash,那么很遗憾我们无法接收similar points。