0

我被困住了。我正在尝试使用选择排序来按字母顺序排列strcmp字符串中的结构。问题是我不知道如何对结构内部的字符串进行选择排序,只使用指针,没有索引。

我的结构看起来像:

struct customer
{
char  customer_name[MAX_NAME_LENGTH];  /* Last name of customer    */
float amount_owed;                     /* Amount customer owes     */
int   priority;                        /* Priority of customer     */
};

和我的函数调用:

sort_customers(quantity, p_customer_records);

和定义:

/**********************************************************************/
/*                     Sort the customer database                     */
/**********************************************************************/
void sort_customers(int quantity, struct customer *p_customer_start)
{
struct customer *p_customer,
                     *p_outer,
                     *p_inner,
                     temp_customer;

for(p_customer = p_customer_start;
    (p_customer-p_customer_start) < quantity; p_customer++)
{
    p_inner = p_customer;

    for(p_outer = p_inner + 1;
        (p_outer-p_inner) <= quantity; p_outer++)
        if(strcmp(p_inner->customer_name, p_outer->customer_name) < 0)
            p_inner = p_outer;

    temp_customer = *p_customer;
    *p_customer   = *p_inner;
    *p_inner      = temp_customer;

    p_inner++;
}
return;
}

老实说,我不知道如何做到这一点。我无法在互联网上或我的书中找到任何可以帮助我解决此问题的东西。现在,此函数将名称向后排序。我很确定这很容易。我只是想念一些东西。我认为另一双眼睛会有所帮助。希望一切都是描述性的,以帮助任何人了解正在发生的事情。

4

1 回答 1

2

你的问题是内循环的循环控制:

for (p_outer = p_inner + 1;
     (p_outer-p_inner) < quantity; p_outer++)

您需要检查数组的开头:

for (p_outer = p_inner + 1;
     (p_outer-p_customer_start) < quantity; p_outer++)

使用下标处理两个数组索引可能会更容易。

工作代码(修复了“交换”打印中的错误):

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

enum { MAX_NAME_LENGTH = 16 };
struct customer
{
    char  customer_name[MAX_NAME_LENGTH];  /* Last name of customer    */
    float amount_owed;                     /* Amount customer owes     */
    int   priority;                        /* Priority of customer     */
};

static void sort_customers(int quantity, struct customer *p_customer_start)
{
    struct customer *p_customer,
                    *p_outer,
                    *p_inner,
                    temp_customer;

    for (p_customer = p_customer_start;
            (p_customer-p_customer_start) < quantity; p_customer++)
    {
        p_inner = p_customer;
        printf("Inner: %s\n", p_inner->customer_name);

        for (p_outer = p_inner + 1;
                (p_outer-p_customer_start) < quantity; p_outer++)
        {
            printf("Compare: %s vs %s\n", p_inner->customer_name, p_outer->customer_name);
            if (strcmp(p_inner->customer_name, p_outer->customer_name) > 0)
                printf("Change!\n"),
                p_inner = p_outer;
        }
        printf("Swap B: %s vs %s\n", p_customer->customer_name, p_inner->customer_name);
        temp_customer = *p_customer;
        *p_customer   = *p_inner;
        *p_inner      = temp_customer;
        printf("Swap A: %s vs %s\n", p_customer->customer_name, p_inner->customer_name);
        //p_inner++;
    }
}

static void dump_customers(int n, struct customer *c)
{
    printf("Customers (%d):\n", n);
    for (int i = 0; i < n; i++)
        printf("%-10s %6.2f %4d\n", c[i].customer_name, c[i].amount_owed, c[i].priority);
}

int main(void)
{
    struct customer data[] =
    {
        { "Max", 23.45, 2 },
        { "Carla", 34.75, 1 },
        { "Zach", 39.21, 22 },
    };
    int quantity = 3;

    dump_customers(quantity, data);
    sort_customers(quantity, data);
    dump_customers(quantity, data);

    return 0;
}

失败版本的输出:

Customers (3):
Max         23.45    2
Carla       34.75    1
Zach        39.21   22
Inner: Max
Compare: Max vs Carla
Change!
Compare: Carla vs Zach
Compare: Carla vs 
Change!
Compare:  vs @?Q?
Compare:  vs 
Swap B: Max vs 
Swap A:  vs Max
Inner: Carla
Compare: Carla vs Zach
Compare: Carla vs Max
Swap B: Carla vs Carla
Swap A: Carla vs Carla
Inner: Zach
Compare: Zach vs Max
Change!
Compare: Max vs @?Q?
Change!
Compare: @?Q? vs 
Change!
Compare:  vs 
Compare:  vs 
Swap B: Zach vs 
Swap A:  vs Zach
Customers (3):
             0.00    0
Carla       34.75    1
            -0.00 32767
Segmentation fault: 11

当它继续运行时,很明显内循环的边界存在问题。

工作版本的输出:

Customers (3):
Max         23.45    2
Carla       34.75    1
Zach        39.21   22
Inner: Max
Compare: Max vs Carla
Change!
Compare: Carla vs Zach
Swap B: Max vs Carla
Swap A: Carla vs Max
Inner: Max
Compare: Max vs Zach
Swap B: Max vs Max
Swap A: Max vs Max
Inner: Zach
Swap B: Zach vs Zach
Swap A: Zach vs Zach
Customers (3):
Carla       34.75    1
Max         23.45    2
Zach        39.21   22

请注意我如何每次都打印有用的信息。这种printf("Change!\n"),表示法并不优雅——但它适用于调试目的。该dump_customers()函数是您应该或多或少地为自己自动编写的东西(并且在调试时经常使用)。当事情出错时,它可以更容易地看到。这不是我最好的转储功能;它应该将标签字符串作为参数,并可能将 aFILE *fp写入。对于更大的数组,它应该在每行前面打印行号。尽管如此,打印每个数据结构的函数的基本思想是非常有帮助的。

于 2013-10-25T23:43:45.143 回答