我有按姓氏排序的算法,但我无法弄清楚如何按姓氏排序,如果两个人姓氏相同,则按姓氏排序。
void sortLastName(FRIEND friends[ARRAY_MAX], int& count) {
FRIEND temp;
for(int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
if (stricmp(friends[i].lastName, friends[j].lastName) > 0) {
temp = friends[i]; //swapping entire struct
friends[i] = friends[j];
friends[j] = temp;
}
}
}
}
===编辑====================
我不想使用STD sort()
答案 0 :(得分:9)
为什么不使用std::sort
?这就是它的用途:
struct NameComparer {
bool operator()(const FRIEND& lhs, const FRIEND& rhs){
int compareResult = stricmp(lhs.lastName, rhs.lastName);
if(compareResult == 0){
compareResult = stricmp(lhs.firstName, rhs.firstName);
}
return compareResult < 0;
}
};
std::sort(friends, friends + ARRAY_MAX, NameComparer());
当然,你也应该使用C ++ std::string
类。这就是它的用途。然后,您不必使用容易出错的C字符串操作函数,例如stricmp
。
答案 1 :(得分:5)
首先,比较姓氏。如果它们相等,则比较名字:
int compareResult = stricmp(friends[i].lastName, friends[j].lastName);
if(compareResult == 0)
compareResult = stricmp(friends[i].firstName, friends[j].firstName);
if(compareResult < 0)
// swap friends[i] and friends[j]
答案 2 :(得分:4)
首先,使用qsort
或正确的C ++等价物,它采用比较两个对象的函数。
比较应该是微不足道的:
int compare_by_name(const FRIEND& f1, const FRIEND& f2)
{
int last_name_matches = strcmpi(f1.lastName, f2.lastName);
return (last_name_matches != 0) ? last_name_matches :
strcmpi(f1.firstName, f2.firstName) ;
}
注意:真正的C ++实现可能会使用比较器函数的模板。
答案 3 :(得分:3)
你必须改变你的比较。基本算法是如果朋友[i]&gt;朋友[j]然后交换他们。因此,请更改“&gt;”的定义包括名字比较。
以下应该做的事情:
if (stricmp(friends[i].lastName, friends[j].lastName) > 0 ||
(stricmp(friends[i].lastName, friends[j].lastName) == 0 &&
stricmp(friends[i].firstName, friends[j].firstName) > 0))
你可能只想做一次姓氏比较(将它存储在临时变量中而不是比较两次),但想法是一样的。
请注意,执行此操作的“最佳”方法可能是在FRIEND类中提供比较函数。然后,您可以改为使用if(friends[i].CompareTo(friends[j]) > 0)
。
答案 4 :(得分:2)
除了选择构建使用这两个名称的比较函数之外,您还可以对姓氏进行排序然后对姓氏进行排序,但您必须注意使用{{3第二遍。也可以在第一次使用它。
好消息:std::stable_sort
可用且保证稳定(感谢Adam和libt进行更正)。普通std::sort
和c标准库qsort
不能保证稳定,但可能会有一些实现。正如马克在评论中指出的那样,你展示的泡泡排序已经稳定了。
单一排序与自定义比较功能的选择效率较低,但它可以让您轻松地让用户在运行时选择多个排序(因为您不必定义每个排序)可能的比较功能,或迷你语言。)
答案 5 :(得分:1)
请不要自己实施排序 - std :: sort(在<algorithm>
中)可以更好,更有效地完成这项工作。 (除了您只是想看看您的算法如何用于实验目的)
无论如何,你必须指定一个比较函数或更好的函数。
struct FriendComparer {
bool operator () (const FRIEND& a, const FRIEND& b) {
// Comparison code here (see previous posts)
}
};
您可以像这样调用它:
std::sort(friendArray, friendArray + count, FriendComparer());
答案 6 :(得分:1)
如果您不介意使用boost.tuple(并替换或至少修改现有的Friend实现),则会有一个包含的比较函数。
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
typedef boost::tuple<std::string, std::string> Friend;
Friend f1, f2;
bool compareFriends = f1 < f2;
以上所有都应该有效。
答案 7 :(得分:0)
添加以下内容:
else if (stricmp(friends[i].lastName, friends[j].lastName) == 0 &&
stricmp(friends[i].firstName, friends[j].firstName) > 0) {
temp = friends[i]; //swapping entire struct
friends[i] = friends[j];
friends[j] = temp;
}
答案 8 :(得分:0)
定义比较函数(或类建议为jalf)并使用STL的std :: sort():
bool compareFriends(FRIEND const & lhs, FRIEND const & rhs)
{
int const resultLast = stricmp(lhs.lastName, rhs.lastName);
if(resultLast == 0)
{
return stricmp(lhs.firstName, rhs.firstName) < 0;
}
else
{
return resultLast < 0
}
}
void sortLastName(FRIEND friends[ARRAY_MAX], int& count)
{
std::sort(friends, friends + count, &compareFriends);
}
答案 9 :(得分:0)
您可以使用左对齐姓氏和名字的串联作为排序键
这是您正在寻找的另一种观点,我认为:)
string key(const FRIEND& aFriend)
{
const int INITIALS_MAX_LENGTH = 200; // assume the worst
string firstNameKeyPart = string(INITIALS_MAX_LENGTH, ' ');
string lastNameKeyPart = string(INITIALS_MAX_LENGTH, ' ');
firstNameKeyPart.replace(0, 0, aFriend.firstName);
lastNameKeyPart.replace(0, 0, aFriend.lastName);
return lastNameKeyPart + firstNameKeyPart;
}
//...
if ( key(friends[i]) > key(friends[j]) )
{
//swap
}
答案 10 :(得分:0)
您可以按姓氏排序,如果姓氏相同,请按名字排序。 像这样的东西(使用冒泡排序):
for (int i = 1; i < dictionary.size(); ++i)
for (int j = 0; j < dictionary.size()-1; ++j) {
if (dictionary[i].Last < dictionary[j].Last)
swap(dictionary[i], dictionary[j]);
}
for (int i = 1; i < dictionary.size(); ++i)
for (int j = 0; j < dictionary.size() - 1; ++j) {
if (dictionary[i].Last == dictionary[j].Last && dictionary[i].First < dictionary[j].First)
swap(dictionary[i], dictionary[j]);
}