为啥我们必须重载“<”运算符才能使用 is_permutation 并包含算法
Posted
技术标签:
【中文标题】为啥我们必须重载“<”运算符才能使用 is_permutation 并包含算法【英文标题】:why do we have to overload the '<' operator to use is_permutation and includes algorithm为什么我们必须重载“<”运算符才能使用 is_permutation 并包含算法 【发布时间】:2019-05-04 10:16:05 【问题描述】:我有一个包含点向量的向量是一个具有 x 和 y 坐标的类。我基本上必须从我的向量中删除所有排列和子集。为此,我使用算法包括和 is_permutation
我已经重载了 '==' 运算符,我们需要它是有道理的。但是除非我重载'
这是我的点课:
class Point
private:
int x;
int y;
public:
Point()
x=0;
y=0;
Point(int xx, int yy)
x=xx;
y=yy;
double getSlope(Point p)
if(this->x!=p.x && this->y!=p.y)
return (double)(double(this->y-p.y)/double(this->x-p.x));
else if(this->x==p.x)
return INT_MAX;
else
return INT_MIN;
void print()
cout<<"(" <<x<<","<<y<<")";
bool operator == (Point &p)
if(this->x==p.x && this->y==p.y )
return true;
else
return false;
bool operator < (Point &p)
cout<<"\nin the < operator\n";
if(this->x < p.x && this->y < p.y )
return true;
else
return false;
;
这是一个接收点的临时向量的函数 并将其与 vector> 进行比较以删除排列。 这些点是从文件中获取的,因此我们只在通过检查时才将其添加到向量中的点
bool check(PointVector temp, vector<PointVector> pointArrays )
for(int i =0 ; i < pointArrays.size(); i++)
if(is_permutation(pointArrays[i].begin(),pointArrays[i].end(),temp.begin()))
return false;
else if(includes(pointArrays[i].begin(),pointArrays[i].end(),temp.begin(),temp.end()))
return false;
else if(includes(temp.begin(),temp.end(),pointArrays[i].begin(),pointArrays[i].end()))
pointArrays[i].swap(temp);
return false;
return true;
点向量是vector<points>;
的类型定义
【问题讨论】:
不重载<
会出现什么错误?
【参考方案1】:
这大约是std::includes
,它对要排序的输入序列提出了要求(根据比较器 - operator<
)。
在这个前提条件下,算法可以用operator==
(语义不是<
而不是>
)和相同的线性渐近复杂度来实现。1对于第一个长度为 n 的范围和长度为 m 的第二个范围,我们迭代第一个范围,每次将元素与第二个范围的当前元素进行比较。在匹配时,我们像往常一样将迭代器增加到两个范围。所以,这是 O(n+m) = O(n),因为 n false
。问题是如果 n > m 并且结果应该是false
,我们必须迭代整个第一个范围来查看(在检查第一个范围的 n - m + 1 个元素与第二个范围的第一个元素之前,我们无法决定)范围)。 n - m 越大越差。
但是使用operator<
,我们可以更快地做出决定(更确切地说,永远不会更晚),我们是否应该从算法中返回false
,因为我们已经从第二个序列中读取了一个元素,该元素在下一个序列之前第一个序列。
示例:
1 是 2, ..., 106 的子范围吗?
operator==
: 106 - 1 次比较 operator<
: 1 次比较
即使是operator<
版本,在这个示例中仍然会受到影响:
106 是 1, ..., 106 - 1 的子范围吗?
operator==
: 106 - 1 次比较 operator<
: 106 - 1 次比较
然后由程序员选择预期的迭代方向以产生更短的决策时间。
总体而言,处理有序序列的算法在顺序比较方面起作用,因为它们可以更深入地了解输入序列。
1. 如果没有对任一范围的排序要求(以及随机访问迭代器),复杂性会更高(取决于使用额外的结构/预排序)。
【讨论】:
以上是关于为啥我们必须重载“<”运算符才能使用 is_permutation 并包含算法的主要内容,如果未能解决你的问题,请参考以下文章
为啥我们在重载赋值中使用 return *this? [复制]
为啥我们需要在 express.js 服务器上使用代理才能获得 webpack 热重载服务器功能与 react-routing 相结合
为啥我们需要在 express.js 服务器上使用代理才能获得与 react-routing 相结合的 webpack 热重载服务器功能