【问题标题】:Generic Ordering Function For Structures in CC中结构的通用排序函数
【发布时间】:2021-05-24 10:59:31
【问题描述】:

所以我有这个问题。我应该创建一些排序函数以在 C 中的通用排序例程中使用。除了一个函数之外,我所有的函数都在工作。该函数应该用作结构的排序函数。代码应按年份排列列表。

以下是已预先编写并用于排序例程的两个辅助函数的代码:

static
void swap(void **left, void **right) {
    void *temp = *left;
    *left = *right;
    *right = temp;
}

void sort_array(void *Array[], unsigned size, int (*ordered)(void *, void *))
{
    int i;
    int have_swapped = 1;

    while (have_swapped) {
        have_swapped = 0;
        for (i = 0; i < size - 1; ++i ){
            if (ordered(Array[i], Array[i+1])) {
                swap(&Array[i], &Array[i+1]);
                have_swapped = 1;
            }
        }
    }
}

然后就是这个函数,也是预写在main中用来测试的。

int main() {
    int i;
    int status = EXIT_SUCCESS;

    sort_array((void**)data, data_size, &ordered_structures);

    for (i = 0; i < data_size - 1; ++i) {
        if (data[i]->year > data[i+1]->year) {
            fprintf(stderr,
                    "\"%s\" and \"%s\" are out of order\n",
                    data[i]->name,
                    data[i+1]->name);
            status = EXIT_FAILURE;
        }
    }

    return status;
}

结构简单。

struct automobile {
    const char *name;
    unsigned year;
    unsigned price;
};

所以这些是使用的辅助函数。我所要做的就是编写一个函数,该函数将用于使用这些辅助函数对结构进行排序。

我的解决方案可以编译,但是没有达到预期的效果,我的解决方案仍然有问题。这是我所拥有的。

int ordered_structures(void *left, void *right) {
     const int *x = left;
     const int *y = right;
     if (x < y)
         return 0;
     else 
         return 1;
}

非常感谢任何帮助

【问题讨论】:

  • @AlexReynolds:main 函数清楚地表明排序是通过增加年数来测试的,但不清楚排序函数应该返回什么来实现这种排序。如果对象是有序的,我认为它应该返回 true。

标签: c pointers structure function-pointers


【解决方案1】:

您的函数将使用 2 个指向 struct automobile 对象的指针调用,您应该比较这些对象的 year 成员:

// return true if swapping should occur. ie: if automobile structures
// are not ordered by their year member (name is inconsistent with semantics)
int ordered_structures(void *left, void *right) {
     const struct automobile *x = left;
     const struct automobile *y = right;
     return (x->year > y->year);
}

请注意以下备注:

  • 名称ordered_structures 与预期语义不一致:如果指针应该交换,即如果对象有序,则返回true。。李>
  • 将指向struct automobile 的指针数组转换为(void **)(指向void 指针数组的指针)不可移植。它不适用于指向不同类型的指针具有不同表示的体系结构。幸运的是,这些架构极为罕见。
  • &amp;ordered_structures 中的 &amp; 是多余的。
  • data_sizeisort_array中的size参数的类型应该一致。 size_t 似乎是更好的选择。
  • 排序算法(冒泡排序)对于大型数组效率低下。 C 库有一个 qsort 函数,它使用更有效的方法,但会采用不同的排序函数(不同的参数和不同的返回值语义)。

【讨论】:

  • 嗯,如果您查看代码,它会在返回 true 时进行交换:'D
  • 即您盯着预先编写的代码越多,它看起来就越糟糕。这实际上非常糟糕。
  • 即当对未排序时,“ordered”函数必须返回 true。
  • @AnttiHaapala:我修改了破坏语义的代码。我还没有阅读排序程序。
【解决方案2】:

您只是在比较 指针,而不是它们所指向的对象中的值。

使用

if (*x < *y) {
    return 0;
}
else {
    return 1;
}

顺便说一句,由于比较运算符 do 返回一个布尔值,你可以直接写

return *x >= *y;

但你是说这些是

struct automobile {...}

那么你需要将指针转换为struct automobile * 并比较其中的成员,所以我猜也许

const struct automobile *x = left;
const struct automobile *y = right;
return x->price > y->price;

按价格升序排序...和

const struct automobile *x = left;
const struct automobile *y = right;
return x->year > y->year;

升年...


附:预先编写的代码看起来非常糟糕,从 (void **) 演员表开始,这不可能是正确的 - 即如果该演员表是需要编译然后代码是错误的,如果不是 需要那么为什么它首先存在。并且排序算法是冒泡排序,被称为“通用坏排序算法”...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 2010-10-26
    • 2011-12-16
    相关资源
    最近更新 更多