查找数组中元素的最高频率(有时它可以工作)

时间:2016-12-10 10:04:20

标签: c loops frequency

您好我的代码遇到了一些问题。有时返回的最大频率是正确的,但有时却不是。发生错误时,它总是返回1太多。我似乎无法找到错误。我试图编写第一个循环nrofpeople-1,但它并没有什么区别。

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

#define MAX 10000

int main(int argc, const char *argv[]) {
    int nrofpeople;
    int array[MAX];
    int num = 0;
    int index;

    srand((unsigned int)time(NULL));

    printf("How many people?");
    scanf("%d", &nrofpeople);

    for (int i = 0; i < nrofpeople; i++) {
        array[i] = rand() % 3 + 1; // generate random number to test
    }

    int maxcount = 0;
    for (int i = 0; i < nrofpeople; i++) {
        index = 1;

        for (int j = 1; j < nrofpeople; j++) {
            if (array[i] == array[j]) {
                index++;
            }
        }
        if (index > maxcount) {
            maxcount = index;
            num = array[i];
        }
    }

    printf("Number: %d Occurred: %d times\n", num, maxcount);
    return 0;
}

4 个答案:

答案 0 :(得分:0)

  

(有时它有效)

我真的很惊讶它有效。在任何情况下,如果要在输入数组中找到最大的条目,可以通过一次传递来完成:

int maxcount = 0;

for (int i=0; i < nrofpeople; i++)
{
    if (array[i] > maxcount)
    {
        maxcount = array[i];
    }
}

您当前正在使用数组上的双循环,如果您需要对数组进行跨产品样式比较,这将是合适的。但这似乎与你的问题陈述不一致。

答案 1 :(得分:0)

如果您打算在给定数组中找到每个数字的频率,您可以创建另一个数组,其中包含原始数组包含的所有元素减去重复的数字。然后,您可以设置一个计数数组来计算原始数组中所有数字的频率。

    int flag = 0, a[nrpeople], k = 0;
    for(int i = 0; i < nrpeople; i++){
    flag = 0;
    for(int j = i+1; j<nrpeople; j++){
        if(array[i] == array[j]){
            flag = 1;
            break;
        }
    }
    if(flag == 0){
        a[k] = array[i];
        k++;
    }
    }
    int count[k] = {0};
    for(int i=0; i<k; i++){
    for(int j = 0; j<nrpeople; j++){
        if(a[i] == array[j])
        count[i]++;
    }
    }

然后用count数组做任何你想做的事。

答案 2 :(得分:0)

您要解决的问题陈述中有一些未清除的区域。如果你为我们提供了几个例子(输入+预期输出),我认为会更好。

无论如何,我读了你的最后一条评论,似乎你想要找到给定数组中最常见(常用)的元素。这是实现这一目标的一种方法。代码中有注释:仔细阅读。

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

#define MAX 10

// gcc main.c -o main -std=c99
// ./main

int main(int argc, const char * argv[])
{
    srand((unsigned int)time(NULL));

    int array[MAX];
    for(int i=0; i<MAX; i++) {
        array[i] = -1; // to make sure there are no uninitialized fields
    }

    int npeople = -1;
    do {
        printf("How many people (1 to %d)? ", MAX);
        scanf("%d", &npeople);
    }
    while(npeople<1 || npeople>MAX);

    // Filling array with integer values in range [min, max]

    const unsigned int min=5;
    const unsigned int max=15;
    for(int i=0; i<npeople; i++) {
        array[i] = min + rand() % (max-min+1);
    }

    // Now searching for the most frequent element

    const int f = max+1;
    int freq[f];
    /* frequency array
     * freq[i] = k means value i appears k times in array
     * And to make things easier, we use up to max+1 fields for the frequency array.
     * But normally, only max-min+1 fields are needed.
     * However in that case, additional conversions (between array and freq)
     * become mandatory.
     */

    // initialization
    for(int i=0; i<f; i++) {
        freq[i] = 0;
    }

    // filling frequency array
    for(int i=0; i<MAX; i++) {
        freq[array[i]]++;
    }

    // Display

    printf("\n");
    printf("Input array\n");
    printf("===========\n");
    for(int i=0; i<MAX; i++) {
        printf("%d", array[i]);
        i==MAX-1 ? printf("\n") : printf(" ");
    }

    printf("\n");
    printf("Frequency array\n");
    printf("===============\n");
    for(int i=0; i<f; i++) {
        printf("%0d", freq[i]);
        i==f-1 ? printf("\n") : printf(" ");
    }

    printf("\n");
    printf("Note\n");
    printf("====\n");
    printf("freq[i] = k MEANS value i appears k times in array\n");

    int mse = -1; // most frequent element
    int h = -1; // highest occurrence
    for(int i=0; i<f; i++) {
        if(freq[i] > h) {
            h = freq[i];
            mse = i;
        }
    }
    printf("\n");
    printf("Conclusion\n");
    printf("==========\n");
    printf("The most frequent element is %d, appearing %d time(s).\n", mse, h);

    return 0;
}

此算法有效,因为我们知道数组中的最小值和最大值。如果我们不这样做,我们可以先使用qsort对数组进行排序,然后我们就能找到数组的极值(极值)。

希望它有所帮助。

答案 3 :(得分:0)

您的代码中存在一些问题:

  • 您不检查输入人数的有效性,导致无效输入的未定义行为。

  • 找到最高频率的算法存在缺陷:array[i]计算i > 0两次。你实际上可以让内循环检查更少的条目,只有第一次出现的给定数字产生最大数量。

以下是改进版本:

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

#define MAX 10000

int main(int argc, const char *argv[]) {
    int nrofpeople;
    int array[MAX];

    printf("How many people?");
    if (scanf("%d", &nrofpeople) != 1 || nrofpeople <= 0 || nrofpeople > MAX) {
        printf("invalid number of people\n");
        return 1;
    }

    srand((unsigned int)time(NULL));
    for (int i = 0; i < nrofpeople; i++) {
        array[i] = rand() % 3 + 1; // generate random number to test
    }

    int num = 0, maxcount = 0;
    for (int i = 0; i < nrofpeople; i++) {
        int count = 1;
        for (int j = i + 1; j < nrofpeople; j++) {
            if (array[i] == array[j]) {
                count++;
            }
        }
        if (count > maxcount) {
            maxcount = count;
            num = array[i];
        }
    }
    printf("Number: %d Occurred: %d times\n", num, maxcount);
    return 0;
}