cs50 pset3排序功能

时间:2016-11-23 17:32:48

标签: c cs50

我在pset3上实现sort函数时遇到问题。我使用过GDB,发现我的sort函数没有排序。我不确定是否存在语法问题,或者逻辑是否有点搞砸了。

void sort(int values[], int n)
{
    for (int k = 0; k < n; k++)
    {
        for (int j = 0; j < n; j++)
        {
            if (values[k] >= values[j])
            {
                 int temp = values[k];
                 values[k] = values[j];
                 values[j] = temp;
            }
        }
    }
} 

2 个答案:

答案 0 :(得分:1)

你很近,但你的循环不太正确 - 改变:

for (int k = 0; k < n; k++)
{
    for (int j = 0; j < n; j++)
    {

为:

for (int k = 0; k < n - 1; k++)
{
    for (int j = k + 1; j < n; j++)
    {

要理解为什么需要进行此更改,请考虑内部循环(j)只需将索引k上方的元素与index {的当前元素进行比较{1}}。所以外部循环(k)需要从k迭代到0(比最后一个元素少一个),并且对于每个外部循环迭代,内部循环需要从{{迭代} 1}}(n - 2之上的第一个元素)到k + 1(最后一个元素)。

  

注意:纯粹的机会似乎原始代码 似乎正常工作,即使它乍一看似乎不应该。我已经使用各种边缘情况对其进行了测试,即使它执行了许多冗余交换,但最终结果似乎总是被排序(令人惊讶的是输出是以降序而固定代码在升序顺序,如预期的那样)。感谢Jonathan Leffler发现这一点 - 请参阅他的answer and demo program

另一个小问题 - 这个测试:

k

应该只是:

n - 1

它不是不正确的(代码仍然可以工作),但交换相等的元素是没有意义的,所以写的效率有点低。

答案 1 :(得分:1)

我把你的代码转换成了一个完整的程序。它比MCVE大,因为它有支持代码用于改组数组,打印结果,以及运行这些的main()当然。

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

static int rand_int(int n)
{
    int limit = RAND_MAX - RAND_MAX % n;
    int rnd;

    while ((rnd = rand()) >= limit)
        ;
    return rnd % n;
}

static void shuffle(int *array, int n)
{
    for (int i = n - 1; i > 0; i--)
    {
        int j = rand_int(i + 1);
        int tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
    }
}

static void print_array(int n, int a[n])
{
    for (int i = 0; i < n; i++)
        printf(" %d", a[i]);
    putchar('\n');
}

static void sort(int values[], int n)
{
    for (int k = 0; k < n; k++)
    {
        for (int j = 0; j < n; j++)
        {
            if (values[k] >= values[j])
            {
                 int temp = values[k];
                 values[k] = values[j];
                 values[j] = temp;
            }
        }
    }
}

int main(int argc, char **argv)
{
    if (argc > 1)
    {
        long l = strtol(argv[1], 0, 0);
        unsigned u = (unsigned)l;
        printf("Seed: %u\n", u);
        srand(u);
    }

    int data3[3] = { 3, 1, 2 };
    print_array(3, data3);
    sort(data3, 3);
    print_array(3, data3);

    int data5[5] = { 0, 2, 6, 1, 5, };
    for (int i = 0; i < 5; i++)
    {
        shuffle(data5, 5);
        print_array(5, data5);
        sort(data5, 5);
        print_array(5, data5);
    }

    int data9[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    for (int i = 0; i < 9; i++)
    {
        shuffle(data9, 9);
        print_array(9, data9);
        sort(data9, 9);
        print_array(9, data9);
    }

    return 0;
}

随机播放代码实现Fisher-Yates shuffle,并且是 基于answer Roland Illig的代码。如果在没有种子参数的情况下调用,则每次都会生成相同的输出。

使用GCC 6.2.0在macOS Sierra 10.12.1上编译和测试代码。

示例输出:

Seed: 123456789
 3 1 2
 3 2 1
 6 0 1 5 2
 6 5 2 1 0
 0 6 1 2 5
 6 5 2 1 0
 0 1 2 6 5
 6 5 2 1 0
 5 0 6 1 2
 6 5 2 1 0
 1 6 5 2 0
 6 5 2 1 0
 0 4 8 3 7 5 1 6 2
 8 7 6 5 4 3 2 1 0
 7 4 0 5 6 8 3 2 1
 8 7 6 5 4 3 2 1 0
 1 2 7 5 0 8 3 6 4
 8 7 6 5 4 3 2 1 0
 3 8 7 5 2 1 0 6 4
 8 7 6 5 4 3 2 1 0
 1 4 2 6 3 0 7 5 8
 8 7 6 5 4 3 2 1 0
 2 3 7 4 8 0 5 6 1
 8 7 6 5 4 3 2 1 0
 3 4 5 8 6 2 0 7 1
 8 7 6 5 4 3 2 1 0
 3 6 7 4 8 2 5 1 0
 8 7 6 5 4 3 2 1 0
 0 8 7 3 4 6 5 1 2
 8 7 6 5 4 3 2 1 0

这显示了数据每次都按降序排序,尽管有不同的随机输入。

相关问题