我正面临着这个棘手的问题,这使我毫无头绪,也无法弄清这个问题。下面是问题陈述。
有100支球队参加比赛(编号1至100),试图解决9个问题。团队可能无法解决任何问题,在这种情况下,total_solved
问题和total_time
将为零。为了简便起见,我维护一个大小为100的静态向量。name
存储组号(1到100)。我使用active
标志来知道一个团队至少提交了1个解决方案(甚至是错误的)。
这是team
类:
class team
{
public:
int total_solved;
int time[9];
int total_time;
bool solved[9];
bool active;
int name;
team()
{
total_solved = total_time = 0;
active = false;
name = -1;
for(int i=0;i<9;i++)
{
solved[i] = false;
time[i] = 0;
}
}
};
这是向量:
for(int i=0;i<100;i++)
{
record.push_back(new team());
}
稍后,我将填充有关团队的数据。这是与这些团队相对应的数据转储:
cout << "Dumping the data\n";
for(auto it=record.begin();it!=record.end();it++)
{
cout << (*it)->name << " " << (*it)->total_solved << " " << (*it)->total_time << " " << ((*it)->active?'Y':'N') << endl;
}
cout << "That's all\n";
Dumping the data
-1 0 0 N
2 0 0 Y
-1 0 0 N
-1 0 0 N
5 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
24 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
34 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
41 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
45 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
58 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
62 0 0 Y
-1 0 0 N
64 0 0 Y
-1 0 0 N
-1 0 0 N
67 0 0 Y
-1 0 0 N
69 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
78 0 0 Y
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
-1 0 0 N
That's all
您可以看到,在这种特定情况下,没有团队可以解决任何问题。而且有些团队不活跃(未提交任何解决方案,name
为-1或active
为false表示)。当我尝试对这100个团队数据进行排序时,发生崩溃。排序标准是团队必须在最短的时间内解决最大的问题。如果有平局,我们将根据团队编号进行排序,而忽略不活动的团队。
bool compare(team *t1, team *t2)
{
if(t1->total_solved != t2->total_solved)
return t1->total_solved > t2->total_solved;
if(t1->total_time != t2->total_time)
return t1->total_time < t2->total_time;
return t1->active;
}
sort(record.begin(),record.end(),compare);
我通过gdb分析,得到以下信息:
Program received signal SIGSEGV, Segmentation fault.
0x00005555555552d0 in compare (t1=0x55555576fec0, t2=0x411) at 10258.cpp:33
33 if(t1->total_solved != t2->total_solved)
t2
肯定得到了无效的指针,但是我想知道为什么吗?
编辑
这是可编译的版本:https://ideone.com/bcnmE0,带有示例输入。
答案 0 :(得分:5)
您的比较功能不正确。如果第一个参数“小于”第二个参数,则比较函数应返回true。但是,如果t1->active
为true,则您的返回true(在所有其他条件相同的情况下)。这意味着对于两个相等的团队,您的函数可能返回true(如果两个团队的active
为true)。不正确的比较功能可能会导致排序算法崩溃。试试这个
bool compare(team *t1, team *t2)
{
if(t1->total_solved != t2->total_solved)
return t1->total_solved > t2->total_solved;
if(t1->total_time != t2->total_time)
return t1->total_time < t2->total_time;
return t1->active > t2->active;
}
或这个
return t1->active < t2->active;
无论哪种方式,对于两个相等的团队,您都返回false。
答案 1 :(得分:0)
如上所述,您需要使比较功能满足Compare的要求。除此之外,当其他字段比较相等时,您的比较功能未考虑团队名称。我从您的示例@ ideone中获取了一些信息,并通过修复以下错误从其中制作了MCVE:
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
#include <array>
class team {
public:
int total_solved;
std::array<int, 9> time;
int total_time;
std::array<bool, 9> solved;
bool active;
int name;
team(int Name) :
total_solved{0},
time{},
total_time{0},
solved{},
active{false},
name(Name)
{}
inline bool operator<(team const& t2) const {
if(total_solved != t2.total_solved)
return total_solved > t2.total_solved;
if(total_time != t2.total_time)
return total_time < t2.total_time;
// return t1->active; // bug
if(active != t2.active) // bug-fix
return active > t2.active; // -"-
// the below was specified as the last sorting criteria
// but wasn't included in your actual code:
return name < t2.name;
}
friend std::ostream& operator<<(std::ostream&, const team&);
};
std::ostream& operator<<(std::ostream& os, const team& t) {
os << t.name << " " << t.total_solved << " "
<< t.total_time << " " << (t.active?"Y":"N") << "\n";
return os;
}
int main() {
// bug-fix: making sure the teams are deleted using std::unique_ptr
std::vector<std::unique_ptr<team>> record;
for(int i=1; i<=100; ++i)
record.emplace_back(new team(i));
for(auto contestant : {41,67,34,2,69,24,78,58,62,64,5,45})
record[contestant-1]->active = true;
std::cout << "Dumping the data\n";
for(auto& t : record) std::cout << *t;
std::sort(record.begin(), record.end(),
[](std::unique_ptr<team> const& a, std::unique_ptr<team> const& b) {
return *a < *b;
}
);
std::cout << "After sort\n";
for(auto& t : record) std::cout << *t;
}