Как отсортировать массив объектов структуры, представляющих расписания - PullRequest
0 голосов
/ 02 марта 2019

Здравствуйте, у меня есть массив объектов 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:1550951769,Sunday (неверно, конечно)

Я не действующий парень, поэтому у меня проблема с пониманием сортировки в этом случае.

Этот код предназначен для Arduino

ОБНОВЛЕНИЕ

Для большей ясности, самое близкое прошлое должно быть по дням недели, а также по ЧЧ: ММ

1 Ответ

0 голосов
/ 02 марта 2019

Если 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) имеет значение true (например, 1), а (a < b) - false (например, 0), ваше условие равно 1 - 0 = 1, поэтому b сортируется до a.Если они равны, результат равен 0 (обмен не требуется).Если (a > b) равно false и (a < b) true, то результат равен -1, поэтому a сортируется до b - точно так же, как результаты strcmp и т. Д.

Edit - Сравнение, если 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 для желаемого условия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...