Проблема с QSORT () - сортировка не выполнена должным образом (C)

StackOverflow https://stackoverflow.com/questions/3903849

  •  29-09-2019
  •  | 
  •  

Вопрос

У меня есть вопрос относительно QSORT.

Это немного странно, но моя функция QSORT не дает мне правильный выход. Странная вещь состоит в том, что некоторые из моих функций сравнения идентичны моим прошедшим проектам, но они не дают мне правильный ввод вообще. Я не уверен, как проверить это.

Например:

int comp_name_asc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;
  return strcmp(prec1->name, prec2->name); 
}

int comp_name_desc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;
  return strcmp(prec2->name, prec1->name);
}

Вторая функция должна быть порядок убывания, но результат идентичен: она всегда в порядке возрастания. Я проверил, чтобы убедиться, что правильная функция вводится в нужное время. REC - это тип для структуры, который я сделал, который имеет параметр имени Char *.

Также (изменено, чтобы избежать переполнения):

int comp_size_asc(const void *a, const void *b)
{
  const Rec *prec1 = (const Rec *) a;
  const Rec *prec2 = (const Rec *) b;

  if (prec1->byteSize > prec2->byteSize)
    return 1;
  else if (prec1->byteSize < prec2->byteSize)
    return -1;
  else
    return 0;
}

Результатом совершенно странный, не возрастающий или нисходящий (т. Е. 500, 515, 100, 200 ...). Bytesize имеет тип OFF_T, полученный путем выполнения:

char *path; // Build the path
struct stat sb;
if (lstat(path, &sb) == 0) {
  // Read sb.st_size

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

Любые идеи или как я могу отладить, это будет приветствоваться. Спасибо.

РЕДАКТИРОВАТЬ:

Добавление звонка в QSORT:

int index = 0;
Rec **array = (Rec **) malloc(sizeof(Rec *) * capacity);
// Adds element to the array...
qsort(array, index, sizeof(Rec *), comp_name_desc);

(Каждый раз, когда элемент добавляется в массив, индекс увеличивается.)

Спасибо.

РЕДАКТИРОВАТЬ:

Решение было дано ниже. Благодарю вас!

Я должен был измениться:

const Rec *prec1 = (const Rec *) a;

к

const Rec *prec1 = *(const Rec **) a;

Из -за того, как я определил свой массив. Спасибо!

Это было полезно?

Решение

У вас есть массив Rec, или, скорее, массив Rec указатели? Я спрашиваю, потому что функция сравнения получает в качестве указателей параметров в массиве, а не непосредственно в ваши записи.

Вот демонстрация обоих способов:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Rec {
  char *name;
} Rec;

/*
 * The pointers a and b point directly into the array,
 * where the Records themselves are.
 */
static int
cmp_Rec_by_name(const void *a, const void *b) {
  const Rec *rec1 = (Rec *)a;
  const Rec *rec2 = (Rec *)b;
  return strcmp(rec1->name, rec2->name);
}

/*
 * The pointers point directly into the array, where
 * not the records but pointers to them are. So they
 * are a pointer to a pointer to a record.
 */
static int
cmp_Rec_ptr_by_name(const void *a, const void *b) {
  const Rec *rec1 = *(Rec **)a;
  const Rec *rec2 = *(Rec **)b;
  return strcmp(rec1->name, rec2->name);
}

static void
sort_Rec(void) {
  Rec record[3];

  record[0].name = strdup("hello");
  record[1].name = strdup("world");
  record[2].name = strdup("how are you");
  qsort(record, 3, sizeof (Rec), cmp_Rec_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i].name);
}

static void
sort_Rec_ptr(void) {
  Rec *(record[3]);

  record[0] = malloc(sizeof (Rec));
  record[1] = malloc(sizeof (Rec));
  record[2] = malloc(sizeof (Rec));
  record[0]->name = strdup("hello");
  record[1]->name = strdup("world");
  record[2]->name = strdup("how are you");
  qsort(record, 3, sizeof (Rec *), cmp_Rec_ptr_by_name);

  for (int i = 0; i < 3; i++)
    printf("%s\n", record[i]->name);
}

int
main() {
  sort_Rec();
  sort_Rec_ptr();
  return 0;
}

Другие советы

Вы никогда не должны сравнивать цифры, вычитая один из другого. Это, как правило, приведет к переполнению с подписанными типами и вообще не будет работать с без знаки. Общая идиома для сравнения номеров с результатом TRI-состояния является следующим

(a > b) - (a < b)

В противном случае ваши функции сравнения выглядят нормально, поэтому проблема должна быть в том, как вы вызываете функцию сортировки.

Услышать, что такое поведение, догадка может быть, что имена на самом деле не являются именами, если strcmp() У меня были обменены два аргумента, и результаты все еще поднимаются. Одно предложение может быть распечатано имена, используя printf, А также уменьшить имена до 2 или 3 (количество записей), чтобы облегчить отладку и проверку, почему он ведет себя так.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top