C - 为什么这个程序打印两个0'

时间:2018-05-09 21:28:37

标签: c merge

这是程序。它需要一组硬编码的整数,并将它们从最小到最大排序。我从一本书中复制了它,但我无法解读它如何做到这一点,所以也许有人可以帮助我理解。

主要

describe Foo do
  it { is_expected.to have_many :bars }
  it { should have_many :bars }
end

MERGE.C

Foo should have many :bars
Failure/Error: it { is_expected.to have_many :bars }
  expected #<Foo:0x007f9f813ce650> to respond to `has_many?` # ./spec/models/foo_spec.rb:4

Foo should have many :bars
Failure/Error: it { should have_many :bars }
  expected #<Foo:0x007f9f84ad3970> to respond to `has_many?` # ./spec/models/foo_spec.rb:5

MERGESORT.C

/* Test merge() and mergesort(). */

#include "mergesort.h"

int main(void) {
    int sz, key[] = {67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1};

    sz = sizeof(key) / sizeof(int);
    printf("Before mergesort:");
    wrt(key, sz);
    mergesort(key, sz);
    printf("After mergesort:");
    wrt(key, sz);
    return 0;
}

MERGESORT.H

/* Merge a[] of size m and b[] of size n into c[]. */
#include "mergesort.h"
void merge(int a[], int b[], int c[], int m, int n)
{
    int i = 0, j = 0, k = 0;

    while (i < m && j < n)
        if (a[i] < b[j])
            c[k++] = a[i++];
        else
            c[k++] = b[j++];
    while (i < m)   /* pick up an remainder */
        c[k++] = a[i++];
    while (j < n)
        c[k++] = b[j++];
}

WRT.C

/* Mergesort: Use merge() to sort an array of size n. */

#include "mergesort.h"
void mergesort(int key[], int n) // n is 0 to begin with
{
    int j,k,m, *w;
    int x,y;

    for (m = 1; m < n; m *= 2)      /*m is a power of 2*/
        if (n < m){
            printf("ERROR: Array size not a power of 2 - bye!\n");
            exit(1);
        }

    w = calloc(m, sizeof(int));     /* allocate workspace */
    assert(w != NULL);             /* check that calloc() worked */
    for (k = 1; k < n; k *= 2) {
        for (j = 0; j < n - k; j += 2 * k)
            /*
              Merge two subarrays of key[] into a subarray of w[].
            */
            merge(key + j, key + j + k, w + j, k, k); // todo: make the two k's not equal
        for (j = 0; j < n; ++j)
            key[j] = w[j];
    }


    free(w);
}

当它打印出来时,有两个零。这是怎么回事?我认为这个秘诀在于mergesort.c,其中包含k值。正如你在底部附近看到的那样,我评论说:“这两个k不相等&#34;”,这是我老师为我提供的简化解决方案。我还输入了x和y整数,这将是单独的k值。但是我不明白,我怎么能将这一个值分成两个?

1 个答案:

答案 0 :(得分:1)

问题在于函数mergesort()的这部分代码:

    for (m = 1; m < n; m *= 2)      /*m is a power of 2*/
    if (n < m){
        printf("ERROR: Array size not a power of 2 - bye!\n");
        exit(1);
    }

这应该检查要排序的数组的大小是否具有2的幂的大小,并且您传递的数组的大小是13(不是幂2):

int sz, key[] = {67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1};

它应该抛出错误并退出,但由于power of 2检查不正确,它会继续进行并且您的合并排序代码无法对不均匀大小的数组进行排序。因此,对于大小不均匀的数组,您得到的输出不正确。

for循环

for (m = 1; m < n; m *= 2) 
            ^^^^^

循环将迭代到m < n并且循环体if条件正在检查

if (n < m){ ....

这将永远不会发生,因为只要m > n循环退出。

我相信您要检查数组的大小是否为2,而不是检查even的强大功能。 要检查尺寸是否甚至,您只需执行以下操作:

   if (n & 1)
   {
       printf("ERROR: Array size not a multiple of 2 - bye!\n");
       exit(1);
   }

使用合并排序对数组进行排序时,并不要求数组的大小应为偶数。您也可以使用合并排序对奇数大小的数组进行排序。检查this answer