首页 > 解决方案 > 计算数组中所有元素的频率

问题描述

问题:给定一个由 n 个整数组成的未排序数组,该数组可以包含从 1 到 n 的整数。某些元素可以重复多次,而其他一些元素可以不存在于数组中。计算所有存在的元素的频率并打印缺失的元素

代码

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

int main() {
    int i, j, x, t, n, m;

    scanf("%d", &t);
    while (t--) {
        scanf("%d",&m);
        int b[m];
        int a[m];
        int c[m];

        for(i = 0; i < m; i++) {
            scanf("%d", &a[i]);
        }
        for (i = 0; i < m; i++) {
            b[i] = i + 1;
        }
    //  for (i = 0; i < m; i++)
        //{
        //  printf("%d ", b[i]);
        //}
        for (i = 0; i < m; i++) {
            c[i] = 0;
        }
        for (i = 0; i < m; i++) {
            for (j = 0; j < m; j++) {
                if (b[j] == a[i]) {
                    c[i] = c[i] + 1;
                }
            }
        }
        for (i = 0; i < m; i++) {
            printf("%d ", c[i]);
        }
    }
}

问题:我得到的输出为 1 1 1 1 1。有人可以指出我的代码中的逻辑错误吗?

标签: c

解决方案


问题是您正在使用i而不是设置您看到的数字j

    for (i = 0; i < m; i++) {
        for (j = 0; j < m; j++) {
            if (want[j] == input[i]) {
                seen[i] = seen[i] + 1;  // HERE
            }
        }
    }

如果你输入2 2 2,那么它会在i0 时匹配。然后它会在i1 时匹配。当它是 2 时会匹配i。所以你在每个点上得到一个 1。i是看到的数字的位置。相反,您想增加j被检查的数字 - 1。

    for (i = 0; i < m; i++) {
        for (j = 0; j < m; j++) {
            if (want[j] == input[i]) {
                seen[j] = seen[j] + 1;
            }
        }
    }

这指出了一种使整个事情更有效率的方法。want没有必要。由于我们想要从 1 到 n 的数字,我们可以使用数组索引 + 1 of seen。而且你不需要每次都重新扫描整个数组,seen可以在阅读时构建。

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

int main() {
    int size;
    scanf("%d",&size);

    int seen[size];
    int input;

    // Initialize seen
    for(int i = 0; i < size; i++) {
        seen[i] = 0;
    }

    // Read input and store how many integers we've seen
    for(int i = 0; i < size; i++) {
        scanf("%d", &input);
        seen[input-1] += 1;
    }

    // Print the counts
    for (int i = 0; i < size; i++) {
        printf("%d: %d ", i+1, seen[i]);
    }
    puts("");
}

推荐阅读