-1

这是我当前的代码:

#include <stdio.h>

int index_x[] = {0,0,1,0,1,0,0,0,1,0,0,1,0};      // any number of elements
int len = sizeof index_x / sizeof*index_x;

int main(void) {

    int arr[len];
    int j = 0;

    for (int i = 0; i < len; i++)
        if (index_x[i])
            arr[j++] = i;                     // save and advance j only if value is "1"

    for (int i = 0; i < j; i++)               // only print below j !
        printf("%d\n", arr[i]);
}

输出:

2
4
8
11

从这个输出中,我想生成另一个数组,它是这些元素之间的差异。在这种情况下,新数组将是 {2,4,3}。(2-4=2, 8-4=4, 11-8=3)。

我目前正在努力解决两件事:

  1. 将当前代码生成的数组保存arr[i]为另一个数组,以便我可以对其进行操作以备将来使用。
  2. 生成“差异数组”。棘手的部分是元素的数量不会是恒定的,因此我无法指定数组大小。
4

2 回答 2

0

我对其进行了更改以尽可能直接地获得差异;内循环非常简单。

尺寸问题,第一部分:我(仍然)试图避免size_t输入,但添加了一些对尺寸的健全性检查。只是为了表明有一个限制。

第二部分:第一个循环提前获得真值的总和。该booldata数组也由字符组成,不被调用index_x。指数为i

第三部分:diffsVLA 得到它的确切大小,即使对于巨大的输入,它也可以是 0。计数后可以在此处添加一些测试,以排除充满“1”的(大)输入。

我添加了复制,带有消息和打印输出。

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

char booldata[] = { 0,0,1,0,1,0,0,0,1,0,0,1,0 };

char sz_overf = sizeof booldata > 0xffffL * 0xffff;   // too-big-flag for exiting...       
int len = sizeof booldata / sizeof * booldata;        // ...to keep len below size_t   

int sum_of_trues (char *booldata, int len) {
    int sum = 0;
    for (int i = 0; i < len; i++)
        if (booldata[i])
            sum++;
    return sum;
}

void print_intarr(int *inta, int len) {
    for (int i = 0; i < len; i++)
        printf("%d\n", inta[i]);
}

int main(void)
{
    if (sz_overf) return 100;                // len might be overflowed    
    int unsigned                             // signed provokes VLA warning: 9 gazillions seems ok, but not 18  
    dsum = sum_of_trues(booldata, len) - 1;  // Invest a counting loop 

    int diffs[dsum],                         // VLA
        di = 0;                              // diffs' index
    int sti = -1;                            // Stored last index containing true

    for (int i = 0; i < len; i++)

        if (booldata[i]) {               // true?

            if (sti >= 0) {              // and is there a left neighbour?
                int diff = i - sti;         // how far away?
                printf("%d\n", diff);       // 1. on-the-fly result
                diffs[di++] = diff;         // 2. for keeps   
            }
            sti = i;                     // remember last "true" 
        }

    printf("Copying %zu bytes from Diff.-Array\n", sizeof diffs);

    int diffscopy[sizeof diffs];
    memcpy(diffscopy, diffs, sizeof diffs);
    print_intarr(diffscopy, dsum);               // dsum or sizeof diffs


    return 0;
}

输出:

2
4
3
Copying 12 bytes from Diff.-Array
2
4
3

没有多选项的内部循环可能看起来像这样:

if (booldata[i]) {
    if (sti >= 0)                     // and is there a left neighbour?
        diffs[di++] = i - st;         // 2. for keeps   
    sti = i;
}

两个数组和三个变量。其余的需要完成这项工作。

BUGS:全错误输入段错误。获得零差异需要一个“真实”...

于 2021-09-08T10:27:35.530 回答
0

将事物分解为函数可能会有所帮助。

int indexes_of_non_zero(int *source, size_t len, int **dest) {
    *dest = malloc(sizeof(int) * len);

    int count = 0;

    for (int i = 0; i < len; i++) {
        if (source[i] != 0) {
            (*dest)[count++] = i;
        }
    }

    *dest = realloc(*dest, sizeof(int) * count);

    return count;
} 

所以我们有一个函数indexes_of_non_zero,它接受一个大小由参数指定的 int 源数组len,然后是一个指向 int 数组的指针,该数组将成为我们输出的目标。

我们可以天真地为目标分配相同数量的内存,然后遍历源数组并存储非零元素的索引。完成后,我们count会知道目标数组的大小。我们使用realloc将数组缩小到所需的大小。关键是我们返回计数,以便我们的main函数知道目标数组有多大。

我们现在可以创建一个diffs函数来对差异做基本相同的事情。

int diffs(int *source, size_t len, int **dest) {
    *dest = malloc(sizeof(int) * (len - 1));

    for (int i = 0; i < (len - 1); i++) {
        (*dest)[i] = abs(source[i] - source[i + 1]);
    }

    return len - 1;
}

将它们与一个函数放在一起(不是为了简洁而复制和粘贴函数实现)main,并记住释放我们使用过的内存,我们得到:

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

int indexes_of_non_zero(int *source, size_t len, int **dest);
int diffs(int *source, size_t len, int **dest);

int main(void) {
    int data[] = {0,0,1,0,1,0,0,0,1,0,0,1,0};
    size_t len = sizeof(data) / sizeof(*data);

    int *nz = NULL;
    int *d = NULL;
    int nzc = indexes_of_non_zero(data, len, &nz);
    int dlen = diffs(nz, nzc, &d);

    for (int i = 0; i < nzc; i++) {
        printf("%d\n", nz[i]);
    }

    for (int i = 0; i < dlen; i++) {
        printf("%d\n", d[i]);
    }

    free(nz);
    free(d);
}

并编译并运行它,输出为:

2
4
8
11
2
4
3
于 2021-09-08T01:18:24.863 回答