【问题标题】:Inserting elements to array in C在C中将元素插入数组
【发布时间】:2020-12-26 23:20:00
【问题描述】:

我的任务是:如果我们查看数组中的任意两个相邻值,如果右侧的值是左侧的两倍,则应将它们的平均值插入到由旧数组组成的新数组之间并且应该打印新元素。我在平均后移动其他元素有问题。并且不允许使用特殊函数或库。我是初学者,希望您能提供帮助。

#include <stdio.h>

int main() {
    int n, i, j;
    double a[100], average;

    printf("Enter the number of elements: ");
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%lf", &a[i]);
    }
    for (i = 0; i < n; i++) {
        if ((a[i + 1] / a[i]) == 2) {
            for (i = j = 0; i < n; ++i)
                b[j++] = a[i];
            if (a[i + 1] / a[i] == 2) 
                average = (a[i + 1] + a[i]) / 2;
            b[j++] =average;
        }
    }
    for (i = 0; i < j; ++i) {
        printf("%lf\n", b[i]);
    }
}

【问题讨论】:

  • 总是检查scanf的返回值,出错则中止。
  • 您可能需要在 printf 格式字符串中添加一个 \n,以分隔打印的数字。
  • 您的数组a 可以容纳100 个元素。如果n &gt; 100,您应该中止。
  • 不允许使用字符串。每次插入元素时我都应该增加数组的大小,我只是不知道如何将其他元素向前移动。
  • 你可以考虑倒过来做。创建一个足够大的输出数组并从输入数组的末尾而不是开头填充它,以防止必须进行任何插入。最后,只需反向打印输出数组。

标签: arrays c


【解决方案1】:

解决问题的一种简单方法是添加double b[199];,然后将所有内容复制过来:

for (i = j = 0; i < n; ++i) {
  b[j++] = a[i];
  if (...) b[j++] = ...;  /* Append the average to b. */
}
for (i = 0; i < j; ++i) {
  printf("%lf\n", b[i]);
}

如果你真的想在a 本身内向前移动元素,那么你可以通过添加一个内部for 循环(和一个额外的循环变量int k;)来实现,它一个接一个地复制元素:

for (k = n++; k > i; --k) {
  a[k] = a[k - 1];
}

【讨论】:

  • 我编辑了代码,但仍然没有得到正确的结果。
【解决方案2】:

为了在数组中插入一个元素,你必须从最后一个向下复制具有较高索引的元素。

还要避免除以可能为零的a[i],正确处理符合插入平均值条件的0,0,并跳过插入的值,避免插入更多的零。

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

int main() {
    int n, i, j;

    printf("Enter the number of elements: ");
    if (scanf("%d", &n) != 1 || n <= 0)
        return 1;

    double *a = malloc(sizeof(*a) * (2 * n - 1));  // allocate the array to the maximum size
    if (a == NULL)
        return 0;

    for (i = 0; i < n; i++) {
        if (scanf("%lf", &a[i]) != 1)
            return 1;
    }
    for (i = 1; i < n; i++) {
        if (a[i] == a[i - 1] * 2) {
            for (j = n; j > i; j--)
                a[j] = a[j - 1];
            a[i] = (a[i - 1] + a[i]) / 2;
            n++;   // increase number of elements
            i++;   // skip the new value
        }
    }
    for (i = 0; i < n; ++i) {
        printf("%f\n", a[i]);
    }
    free(a);
    return 0;
}

【讨论】:

  • 我试图编译这个,对于 1 2 3 它只会插入 1 和 2 之间的平均值,但不会插入 2 和 3 之间的平均值,所以新数组是 1 1.5 2 3
  • 为什么要在23之间插入任何东西? 3 没有2 的两倍大。
  • 我错了,我忘记了
  • 而且我无法将数组分配给 2*n-1,因为标准 C 中的数组声明中不允许使用变量。
  • @Michael:C99 允许 VLA(可变长度数组),但 C++ 不允许,它们在 C11 中已成为可选,尽管得到广泛支持。我已经更新了答案,从堆中分配数组,如果n太大,最好避免UB。
【解决方案3】:

要在特定位置插入元素,您需要移动数组的其余部分。但是多次这样做很昂贵,您可能更喜欢使用数组来存储要插入元素的位置,然后一次将它们全部插入。

或者,您可以创建一个新数组,在其中复制原始值和新值。

但是有一种更简单、更快捷的方法,即在填充原始数组的同时立即添加新值。这是一个可以做到这一点的程序。

#include <stdio.h>

#define SIZE 100

int main() {
    
    int i, n, avg = 0;
    double a[SIZE];
    
    while( puts("Enter the number of elements:") && (scanf("%d", &n) != 1 || n < 1 || n > SIZE) );
    
    scanf("%lf", &a[0]);
    
    for(i = 1; i < n+avg && i < SIZE-1 && scanf("%lf", &a[i]) == 1; i++) {
        
        if( a[i] == a[i-1] * 2 ) {
            
            a[i+1] = a[i];
            a[i] = (a[i] + a[i-1]) / 2;
            ++avg;
            ++i;
        }
    }
    
    for(i = 0; i < n+avg; i++) {
        
        printf("%lf\n", a[i]);
    }
    
    return 0;
}

【讨论】:

  • i &lt; SIZE 应该是 i &lt; SIZE - 1,以防最后一个元素符合条件。
  • 您的方法很聪明,可以避免教 OP 如何在数组中插入值,这似乎是赋值的目标:)
  • @chqrlie 我的,我的 - 手掌。评论发送到阴间。
  • 他的意思是a[i]/2a[i]/2a[i-1] 你必须插入两者的平均值
  • @Davide:如果右边的比左边的大两倍有点令人困惑,但应该转换为a[i] == 2 * a[i-1]。如果 OP 意味着增加 200%,那么另一个读数将给出 a[i] == 3 * a[i-1]
猜你喜欢
  • 2017-11-06
  • 2023-03-26
  • 2017-12-13
  • 2019-03-08
  • 1970-01-01
  • 2014-12-10
  • 2015-10-22
  • 2018-02-04
  • 2016-01-08
相关资源
最近更新 更多