如何对表示时间表的数组结构对象进行排序

时间:2019-03-01 22:27:47

标签: c arrays sorting struct

您好,我有一个表示时间表的结构对象数组。我需要对它们进行排序,以使排序后的第一个元素最接近当前日期。

结构如下:

struct ScheduleItem {
   int index;
   int hh;
   int mm;
   int dow;
   long reg_timestamp;
};

index =>任意索引号 hh =>小时(24) mm =>分钟 dow =>星期几(从星期日开始= 0) reg_timestamp =>创建时间表的时代时间

以下是样本时间表,它们存储在名为user_schedules的时间表数组中。

index:HH:MM:DOW:EPOCH

1:20:30:0:1550951769
2:03:15:0:1550951769
2:20:30:1:1550951769
3:03:15:1:1550951769
3:20:30:2:1550951769
4:03:15:2:1550951769
4:20:30:3:1550951769
5:03:15:3:1550951769
6:03:15:4:1550951769

假设今天是2:00 am Saturday(dow = 6)

如何使用qsort对其进行排序 数组按顺序排序,第一个元素是当前日期的closest past。我只知道升序或降序排序,所以无法得到想要的东西。

这是我尝试过的

qsort((void *) &applicable_schedules, counter, sizeof(struct ScheduleItem), (compfn)nearestPast );      
candidate = applicable_schedules[0];

/**
 * Compare to sort nearest past schedule
 */
int nearestPast(struct ScheduleItem *elem1, struct ScheduleItem *elem2)
{
  if ( elem1->reg_timestamp == elem2->reg_timestamp)
  {
    return abs(elem1->dow - elem2->dow);    
  }
  else
  {
    return elem1->reg_timestamp - elem2->reg_timestamp;
  }
}

我得到了20:30:0:1550951769Sunday(课程不正确)

我不是c专家,因此在这种情况下对理解排序有疑问。

此代码适用于arduino

更新

为进一步澄清,最接近的过去应该是星期几以及HH:MM

1 个答案:

答案 0 :(得分:1)

如果reg_timestamp仅是从纪元以来的秒数,并且您想按降序对条目进行排序,那么您要做的就是:

int compare_sched_item_time (const void *a, const void *b)
{
    /* cast pointers to adjacent elements to struct ScheduleItem* */
    struct ScheduleItem *x = a, *y = b;

    /* (x->time < y->time) - (x->time > y->time) - descending sort
     * comparison avoids potential overflow
     */
    return (x->reg_timestamp < y->reg_timestamp) - 
           (x->reg_timestamp > y->reg_timestamp);
}

注意:条件表达式的不同避免了潜在的溢出。您可以将其与任何数字类型一起使用。形式为:

/* (a > b) - (a < b) - ascending sort */

/* (a < b) - (a > b) - descending sort */

只需仔细考虑案例。为了提升(a > b)为真(例如1)和(a < b)为假(例如0)的情况,您的条件为1 - 0 = 1,因此b进行排序在a之前。如果它们相等,则结果为0(无需交换)。如果(a > b)为假,(a < b)为真,则结果为-1,因此ab之前排序-就像strcmp的结果一样等等。

编辑-如果reg_timestamp值相等,则进行比较

如果您希望对多个条件进行排序,只需按照重要性递减的顺序进行测试,例如

int compare_sched_item_time (const void *a, const void *b)
{
    /* cast pointers to adjacent elements to struct ScheduleItem* */
    struct ScheduleItem *x = a, *y = b;

    /* (x->time < y->time) - (x->time > y->time) - descending sort
     * comparison avoids potential overflow
     */
    if (x->reg_timestamp != y->reg_timestamp)
        return (x->reg_timestamp < y->reg_timestamp) - 
               (x->reg_timestamp > y->reg_timestamp);
    /* compare dow next */
    else if (x->dow != y->dow)
        return (x->dow < y->dow) - (x->dow > y->dow);
    /* compare hh next */
    else if (x->hh != y->hh)
        return (x->hh < y->hh) - (x->hh > y->hh);
    /* finally compare mm */
    else
        return (x->mm < y->mm) - (x->mm > y->mm);
}

这是qsort的好处。您可以按照自己希望的任何方式对任何元素进行排序,只需返回-1, 0, 1即可达到所需条件。