C++ 自定义比较器不工作 MWE
C++ custom comparator not working MWE
我知道关于这个的 post 已经很少了,所以请随意删除我的 post,但是这段代码:
#include <bits/stdc++.h>
#define tol 1e-9
using namespace std;
int n;
vector<pair<double,double>> vec;
struct comparator {
bool operator () ( pair<double,double> &a, pair<double,double> &b ) {
if ( fabs(a.first-b.first) < tol )
return a.second < b.second;
return a.first > b.first;
}
};
int main() {
int i,j,k,ts,cs= 0,m,sz;
for ( ; 1 == scanf("%d",&n); ) {
for ( vec.clear(), vec.reserve(n), i = 0; i < n; ++i )
scanf("%lf %lf",&vec[i].second,&vec[i].first);
sort(vec.begin(),vec.end(),comparator());
for ( i = 0; i < n; ++i )
printf("%lf %lf\n",vec[i].first,vec[i].second);
}
return 0;
}
不适用于此示例:
2
120 60
60 90
我编译为g++ -std=c++11 -o a mwe.cpp
,我的是g++ version 5.4
您将 resize()
与 reserve()
混淆了。
写的时候
for ( vec.clear(), vec.reserve(n), i = 0; i < n; ++i )
您为向量 vec
保留大小 n
,即您指示 vec
为将来扩展到 n
元素保留内存大小。但是,目前 vec
的大小仍为零。
所以,当你写
scanf("%lf %lf",&vec[i].second,&vec[i].first);
你在写未初始化的对象。
非常非常糟糕。
从技术上讲:您处于 UB(未定义行为)状态。
实际上:一切皆有可能。
写的时候
sort(vec.begin(),vec.end(),comparator());
您正在对大小为零的向量 vec
进行排序,其中 vec.begin()
等于 vec.end()
。
换句话说:std::sort()
什么都不做。
解决方案:避免使用 clear()
(正如 Caleth 所指出的,如果您在 resize()
之后重置所有元素是多余的)并使用 resize()
而不是 reserve()
// -------vvvvvv
for ( vec.resize(n), i = 0; i < n; ++i )
题外话建议:
- 避免not-standard包含为
bits/stdc++.h
- 避免使用旧的 C I/O 并使用新的 C++;所以没有
std::scanf()
和 std::printf()
并使用 std::cin
和 std::cout
.
我认为你真的应该练习你的——用我的话说——笔迹。该片段看起来真的不可读。循环初始值设定项中有这么多语句。第三个循环可以使用 range-based 语法。我倾向于尽可能避免使用传统的 for 循环。
您可以在开始时保留并继续push_back直到假设容量用完。
我知道关于这个的 post 已经很少了,所以请随意删除我的 post,但是这段代码:
#include <bits/stdc++.h>
#define tol 1e-9
using namespace std;
int n;
vector<pair<double,double>> vec;
struct comparator {
bool operator () ( pair<double,double> &a, pair<double,double> &b ) {
if ( fabs(a.first-b.first) < tol )
return a.second < b.second;
return a.first > b.first;
}
};
int main() {
int i,j,k,ts,cs= 0,m,sz;
for ( ; 1 == scanf("%d",&n); ) {
for ( vec.clear(), vec.reserve(n), i = 0; i < n; ++i )
scanf("%lf %lf",&vec[i].second,&vec[i].first);
sort(vec.begin(),vec.end(),comparator());
for ( i = 0; i < n; ++i )
printf("%lf %lf\n",vec[i].first,vec[i].second);
}
return 0;
}
不适用于此示例:
2
120 60
60 90
我编译为g++ -std=c++11 -o a mwe.cpp
,我的是g++ version 5.4
您将 resize()
与 reserve()
混淆了。
写的时候
for ( vec.clear(), vec.reserve(n), i = 0; i < n; ++i )
您为向量 vec
保留大小 n
,即您指示 vec
为将来扩展到 n
元素保留内存大小。但是,目前 vec
的大小仍为零。
所以,当你写
scanf("%lf %lf",&vec[i].second,&vec[i].first);
你在写未初始化的对象。
非常非常糟糕。
从技术上讲:您处于 UB(未定义行为)状态。
实际上:一切皆有可能。
写的时候
sort(vec.begin(),vec.end(),comparator());
您正在对大小为零的向量 vec
进行排序,其中 vec.begin()
等于 vec.end()
。
换句话说:std::sort()
什么都不做。
解决方案:避免使用 clear()
(正如 Caleth 所指出的,如果您在 resize()
之后重置所有元素是多余的)并使用 resize()
而不是 reserve()
// -------vvvvvv
for ( vec.resize(n), i = 0; i < n; ++i )
题外话建议:
- 避免not-standard包含为
bits/stdc++.h
- 避免使用旧的 C I/O 并使用新的 C++;所以没有
std::scanf()
和std::printf()
并使用std::cin
和std::cout
.
我认为你真的应该练习你的——用我的话说——笔迹。该片段看起来真的不可读。循环初始值设定项中有这么多语句。第三个循环可以使用 range-based 语法。我倾向于尽可能避免使用传统的 for 循环。 您可以在开始时保留并继续push_back直到假设容量用完。