Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 自定义排序,是否始终强制0返回升序? 前提_C++_Sorting - Fatal编程技术网

C++ 自定义排序,是否始终强制0返回升序? 前提

C++ 自定义排序,是否始终强制0返回升序? 前提,c++,sorting,C++,Sorting,这个问题有一个已知的解决方案(实际上如下所示),我只是想知道是否有人有一个更优雅的算法或任何其他想法/建议,如何使它更具可读性、效率或健壮性 背景 我有一个体育比赛的列表,我需要按数组排序。由于该数组的填充性质,95%的时间列表将被预先排序,因此我使用改进的冒泡排序算法对其进行排序(因为它接近O(n),几乎排序的列表) 冒泡排序有一个名为compareCompetions的助手函数,它比较两个竞争,如果comp1更大,则返回>0,如果可以,修改优先级方案似乎是最优雅的,这样您就可以正常排序了。例

这个问题有一个已知的解决方案(实际上如下所示),我只是想知道是否有人有一个更优雅的算法或任何其他想法/建议,如何使它更具可读性、效率或健壮性

背景 我有一个体育比赛的列表,我需要按数组排序。由于该数组的填充性质,95%的时间列表将被预先排序,因此我使用改进的冒泡排序算法对其进行排序(因为它接近O(n),几乎排序的列表)


冒泡排序有一个名为compareCompetions的助手函数,它比较两个竞争,如果comp1更大,则返回>0,如果可以,修改优先级方案似乎是最优雅的,这样您就可以正常排序了。例如,不是将默认优先级存储为0,而是将其存储为999,并将用户定义的优先级限制为998。这样您就不必再处理这种特殊情况了,您的比较函数可以有一个更简单的结构,没有if的嵌套: (伪代码)

if(priority1priority2)返回1;
if(startTime1startTime2)返回1;
if(teamName1teamName2)返回-1;
返回0;//完全匹配!

如果可以,修改优先级方案似乎是最优雅的,这样您就可以正常排序了。例如,不是将默认优先级存储为0,而是将其存储为999,并将用户定义的优先级限制为998。这样您就不必再处理这种特殊情况了,您的比较函数可以有一个更简单的结构,没有if的嵌套: (伪代码)

if(priority1priority2)返回1;
if(startTime1startTime2)返回1;
if(teamName1teamName2)返回-1;
返回0;//完全匹配!

您还可以使用如下三元运算符来减少一些代码的冗余度:

int CompareCompetitions(const SWI_COMPETITION &comp1,const SWI_COMPETITION &comp2)
{

if(comp1.nPriority == comp2.nPriority)
{
    //Priorities equal
    //Compare start time
    int ret = comp1.sStartTime24Hrs.CompareNoCase(comp2.sStartTime24Hrs);

    return ret != 0 ? ret : comp1.sHLongName.CompareNoCase(comp2.sHLongName);
}
else if(comp1.nPriority > comp2.nPriority)
    return comp2.nPriority <= 0 ? -1 : 1;
else /*(comp1.nPriority < comp2.nPriority)*/
    return comp1.nPriority <= 0 ? 1 : -1;
}
int CompareCompetitions(恒速SWI_COMPETITION&comp1,恒速SWI_comp2)
{
if(comp1.nPriority==comp2.nPriority)
{
//优先权平等
//比较开始时间
int ret=comp1.sStartTime24Hrs.CompareNoCase(comp2.sStartTime24Hrs);
return ret!=0?ret:comp1.sHLongName.CompareNoCase(comp2.sHLongName);
}
否则如果(组件1.n优先级>组件2.n优先级)

return comp2.nPriority您还可以使用如下三元运算符减少一些代码的冗余度:

int CompareCompetitions(const SWI_COMPETITION &comp1,const SWI_COMPETITION &comp2)
{

if(comp1.nPriority == comp2.nPriority)
{
    //Priorities equal
    //Compare start time
    int ret = comp1.sStartTime24Hrs.CompareNoCase(comp2.sStartTime24Hrs);

    return ret != 0 ? ret : comp1.sHLongName.CompareNoCase(comp2.sHLongName);
}
else if(comp1.nPriority > comp2.nPriority)
    return comp2.nPriority <= 0 ? -1 : 1;
else /*(comp1.nPriority < comp2.nPriority)*/
    return comp1.nPriority <= 0 ? 1 : -1;
}
int CompareCompetitions(恒速SWI_COMPETITION&comp1,恒速SWI_comp2)
{
if(comp1.nPriority==comp2.nPriority)
{
//优先权平等
//比较开始时间
int ret=comp1.sStartTime24Hrs.CompareNoCase(comp2.sStartTime24Hrs);
return ret!=0?ret:comp1.sHLongName.CompareNoCase(comp2.sHLongName);
}
否则如果(组件1.n优先级>组件2.n优先级)
return comp2.n优先级不就是这样吗

if (a==b) return other_data_compare(a, b);
if (a==0) return 1;
if (b==0) return -1;
return a - b;
不就是这样吗

if (a==b) return other_data_compare(a, b);
if (a==0) return 1;
if (b==0) return -1;
return a - b;

我认为您对解决方案的不雅感来自于零优先级异常的重复代码。解释了源代码中的每一条信息都应该用“一个true”来定义对于阅读函数的天真程序员来说,您希望异常在一个地方突出,与其他逻辑分离,以便易于理解。这怎么样

    if(comp1.nPriority == comp2.nPriority)
    {
        // unchanged
    }
    else
    {
        int result, lowerPriority;
        if(comp1.nPriority > comp2.nPriority)
        {
            result = 1;
            lowerPriority = comp2.nPriority;
        }
        else
        {
            result = -1;
            lowerPriority = comp1.nPriority;
        }

        // zero is an exception: always goes last
        if(lowerPriority == 0)
            result = -result;

        return result;
    }

我认为您对解决方案的不雅感来自于零优先级异常的重复代码。解释了源代码中的每一条信息都应该用“一个true”来定义对于阅读函数的天真程序员来说,您希望异常在一个地方突出,与其他逻辑分离,以便易于理解。这怎么样

    if(comp1.nPriority == comp2.nPriority)
    {
        // unchanged
    }
    else
    {
        int result, lowerPriority;
        if(comp1.nPriority > comp2.nPriority)
        {
            result = 1;
            lowerPriority = comp2.nPriority;
        }
        else
        {
            result = -1;
            lowerPriority = comp1.nPriority;
        }

        // zero is an exception: always goes last
        if(lowerPriority == 0)
            result = -result;

        return result;
    }

如果情况nPriority1<0和nPriority2<0但nPriority1!=nPriority2,则不比较其他数据,这是有意的吗

如果不是,我会用

int nPriority1 = comp1.nPriority <= 0 ? INT_MAX : comp1.nPriority;
int nPriority2 = comp2.nPriority <= 0 ? INT_MAX : comp2.nPriority;

if (nPriority1 == nPriority2) {
   // current code
} else {
   return nPriority1 - nPriority2;
}

int-nPriority1=comp1.nPriority如果情况nPriority1<0和nPriority2<0,但nPriority1!=nPriority2,则不比较其他数据,这是有意的吗

如果不是,我会用

int nPriority1 = comp1.nPriority <= 0 ? INT_MAX : comp1.nPriority;
int nPriority2 = comp2.nPriority <= 0 ? INT_MAX : comp2.nPriority;

if (nPriority1 == nPriority2) {
   // current code
} else {
   return nPriority1 - nPriority2;
}

int-nPriority1=comp1.nPriorityI对其进行了Java化,但该方法在C++中运行良好:

int CompareCompetitions(Competition comp1, Competition comp2) {
    int n = comparePriorities(comp1.nPriority, comp2.nPriority);
    if (n != 0)
        return n;
    n = comp1.sStartTime24Hrs.compareToIgnoreCase(comp2.sStartTime24Hrs);
    if (n != 0)
        return n;
    n = comp1.sHLongName.compareToIgnoreCase(comp2.sHLongName);
    return n;
}

private int comparePriorities(Integer a, Integer b) {
    if (a == b)
        return 0;
    if (a <= 0)
        return -1;
    if (b <= 0)
        return 1;
    return a - b;
}
int CompareCompetitions(竞赛comp1,竞赛comp2){
int n=比较优先级(comp1.n优先级,comp2.n优先级);
如果(n!=0)
返回n;
n=组件1.ssStartTime24小时与信号案例(组件2.ssStartTime24小时)相比;
如果(n!=0)
返回n;
n=comp1.sHLongName.CompareTIgnoreCase(comp2.sHLongName);
返回n;
}
私有整数比较优先级(整数a、整数b){
如果(a==b)
返回0;

如果(aI)将其Java化,但该方法在C++中可以正常工作:

int CompareCompetitions(Competition comp1, Competition comp2) {
    int n = comparePriorities(comp1.nPriority, comp2.nPriority);
    if (n != 0)
        return n;
    n = comp1.sStartTime24Hrs.compareToIgnoreCase(comp2.sStartTime24Hrs);
    if (n != 0)
        return n;
    n = comp1.sHLongName.compareToIgnoreCase(comp2.sHLongName);
    return n;
}

private int comparePriorities(Integer a, Integer b) {
    if (a == b)
        return 0;
    if (a <= 0)
        return -1;
    if (b <= 0)
        return 1;
    return a - b;
}
int CompareCompetitions(竞赛comp1,竞赛comp2){
int n=比较优先级(comp1.n优先级,comp2.n优先级);
如果(n!=0)
返回n;
n=组件1.ssStartTime24小时与信号案例(组件2.ssStartTime24小时)相比;
如果(n!=0)
返回n;
n=comp1.sHLongName.CompareTIgnoreCase(comp2.sHLongName);
返回n;
}
私有整数比较优先级(整数a、整数b){
如果(a==b)
返回0;

如果(a只要最高优先级不大于INT_MAX/2,您就可以这样做

#include <climits>

const int bound = INT_MAX/2;
int pri1 = (comp1.nPriority + bound) % (bound + 1);
int pri2 = (comp2.nPriority + bound) % (bound + 1);
根据编译器/硬件的不同,您可以通过将最后一行替换为

return (pri1 > pri2) * 2 - 1;

或(假设2的补码)

最后的评论:你真的想要
compareCompetions
返回1,-1,0吗?如果你所需要的只是冒泡排序,你最好使用一个函数返回
bool
true
如果
comp1
是“
=
comp2
false
否则).这将简化(尽管稍微简化)co