gpt4 book ai didi

c++ - 对象集的排序不正确

转载 作者:太空宇宙 更新时间:2023-11-04 14:47:00 25 4
gpt4 key购买 nike

当我打印整套时,结果未排序并且包含一个重复项。对象 Person 有姓氏、姓氏和出生年份(这 3 个都是字符串)。我首先按出生年份排序,然后按姓氏排序。就其本身而言,没有相同的人(但即使是这样,也应该在将它们插入 set 时将其删除)。

更具体地说,我创建了一组这样的人:

std::set <Person> greatUncles; 

然后像这样插入它们:

greatUncles.insert(Person("bla", "bla", "1900"));

下面是 Person 类的基本内容:

class Person {
public:
//...

Person(std::string s, std::string f, std::string y)
:surname(s), familyname(f), yearOfBirth(y)
{
}

//...

std::string getSurname() const {
return surname;
}

std::string getFamilyname() const {
return familyname;
}

std::string getYearOfBirth() const {
return yearOfBirth;
}

private:
std::string surname;
std::string familyname;
std::string yearOfBirth;
};

//to print the set, overload the '<<' operator
std::ostream &operator<<(std::ostream &o, const Person &person) {
o << person.getSurname() << " "
<< person.getFamilyname() << " "
<< person.getYearOfBirth() << std::endl;
return o;
}

//to order the set, overload the '<' operator
bool operator< (Person const &p1, Person const &p2) {
int compareYearOfBirth = p1.getYearOfBirth().compare(p2.getYearOfBirth());

if (compareYearOfBirth == 0) {
int compareFamilyname = p1.getFamilyname().compare(p2.getFamilyname());
if (compareFamilyname == 0) {
return p1.getSurname().compare(p2.getSurname());
} else
return compareFamilyname;
} else
return compareYearOfBirth;
}

下面是我如何打印叔祖父的集合:

void printGreatUncles(std::set <Person> &greatUncles) {
std::ofstream outputFile;
outputFile.open("greatuncle.dat");

if (outputFile.is_open()) {
for(Person const & person:greatUncles) {
outputFile << person;
}
outputFile.close();
}
}

现在某种情况下的输出应该是这样的(按年份排序):

Sebastian Furtweger 1942
Nikolaus Furtweger 1951
Archibald Furtweger 1967

但它看起来像这样:

Archibald Furtweger 1967
Sebastian Furtweger 1942
Nikolaus Furtweger 1951
Archibald Furtweger 1967

我一辈子都弄不明白自己做错了什么。

最佳答案

std::set要求比较器提供严格的弱排序。其中一部分是如果 a < b == true然后 b < a == false但你没有这个。假设出生年份和姓氏相同,只有姓氏不同。在您的示例中,您将返回一些转换为 true 的正数或负数。因为只有 0false .如果向后运行检查,则会得到相反的整数值,但结果仍为 true。 .

修复此 C++11 提供 std::tie你可以用它来构建一个std::tuple成员及其operator <旨在做正确的事。这让你的代码看起来像

bool operator< (Person const &p1, Person const &p2) {
return std::tie(p1.getYearOfBirth(), p1.getFamilyname(), p1.getSurname()) <
std::tie(p2.getYearOfBirth(), p2.getFamilyname(), p2.getSurname());
}

如果你想继续这样做并且可以使用 C++20,那么你可以添加到 Person

auto operator<=>(const Person&) const = default;

这将自动为您提供运算符 ==、!=、<、<=、> 和 >= Person只要您希望所有成员按照它们在类中定义的顺序进行比较,它们就会“做正确的事”。

关于c++ - 对象集的排序不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54406933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com