按结尾排序第一个名称

时间:2009-05-14 17:07:08

标签: c++ sorting struct

我有按姓氏排序的算法,但我无法弄清楚如何按姓氏排序,如果两个人姓氏相同,则按姓氏排序。

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()

11 个答案:

答案 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]);
    }