查找数组的最高频率以及具有该频率的所有元素

Posted

技术标签:

【中文标题】查找数组的最高频率以及具有该频率的所有元素【英文标题】:Finding the highest frequency of an array and all elements which have that frequency 【发布时间】:2021-12-11 03:31:42 【问题描述】:

我被要求从元素数组和具有所述频率的所有元素中找到最高频率。我的代码似乎工作得很好,但是当我提交它时它似乎有一个错误。谁能帮我找出错误?

格式输入: 第一行包含一个整数 T,表示测试用例的数量。对于每个测试用例,第一行包含一个整数 N,表示数组中元素的数量。下一行包含 N 个整数 Xi (1≤i≤N),表示数组中的第 i 个元素。

格式化输出: 由 T 行组成,其中每行的格式为“Case #X: Y”,其中 X 是从 1 开始的测试用例编号,Y 是最高频率。下一行包含按升序排序的具有该频率的所有元素。

约束: 1 ≤ T ≤ 20 | 2 ≤ N ≤ 20.000 | 1≤Xi≤2×10^5

示例输入:

3
8
1 1 2 2 3 4 5 5
8
5 5 4 3 2 2 1 1 
4
1 1 1 3

样本输出:

Case #1: 2
1 2 5
Case #2: 2
1 2 5
Case #3: 3
1

这是我的代码:

#include <stdio.h>

int main() 
    int T, N[20];

    scanf("%d", &T); getchar();
    
    int A[T][20000];
    
    
    
    for (int i = 0; i<T; i++) 
        scanf("%d", &N[i]); getchar();
        for (int j = 0; j<N[i]; j++) 
            scanf("%d", &A[i][j]); getchar();
        
        
        int X = 0;
        
        for (int j = 0; j<N[i]; j++) 
            for (int k = j + 1; k<N[i]; k++) 
                if (A[i][k]<A[i][j]) 
                    X = A[i][j];
                    A[i][j] = A[i][k];
                    A[i][k] = X;
                
            
        
    
    
    int f[20000];
    
    for (int i = 0; i<T; i++) 
        int c = 0, mc = 0;
        
        for (int j = 0; j<N[i]; j++) 
            c = 1;
            if(A[i][j] != -1) 
                for (int k = j+1; k<N[i]; k++) 
                    if (A[i][j] == A[i][k]) 
                        c++;
                        A[i][k] = -1;
                        
                       
                
                
                f[j]=c;
               
            if (c>mc) 
                    mc = c;
                
        
        printf("Case #%d: %d\n", i+1, mc);
        
        for (int j = 0; j<N[i]; j++) 
            if (A[i][j] != -1) 
                if (f[j] == mc) 
                    printf ("%d", A[i][j]);
                    if (j<N[i]-1) 
                        printf(" ");
                    
                
                
            
            
        
        
        printf("\n");
        
    
    
    return 0;

编辑 所以我制作了另一个代码,而不是一次输入所有数组并一次输出所有内容,该代码在我输入第一个数字数组后输出频率和元素。但似乎代码仍然有问题,我找不到在哪里...... P.s 我对此很陌生,所以我为我的代码缺乏效率表示歉意。

新代码

#include <stdio.h>

int main() 
    int T, N;

    scanf("%d", &T); getchar();
    
    int A[20000];
    
    for (int i = 0; i<T; i++) 
        scanf("%d", &N); getchar();
        for (int j = 0; j<N; j++) 
            scanf("%d", &A[j]); getchar();
        
        
        int X;
        
        for (int j = 0; j<N; j++) 
            for (int k = j + 1; k<N; k++) 
                if (A[k]<A[j]) 
                    X = A[j];
                    A[j] = A[k];
                    A[k] = X;
                
            
        
        
        int f[N], c = 0, mc = 0;
        
        for (int j = 0; j<N; j++) 
            c = 1;
            if(A[j] != -1) 
                for (int k = j+1; k<N; k++) 
                    if (A[j] == A[k]) 
                        c++;
                        A[k] = -1;
                       
                
                f[j]=c;
                if (c>mc) 
                        mc = c;
                
               
        
        printf("Case #%d: %d\n", i+1, mc);
        
        for (int j = 0; j<N; j++) 
            if (A[j] != -1) 
                if (f[j] == mc) 
                    printf ("%d", A[j]);
                    if (j<N-1) 
                        printf(" ");
                    
                   
               
        
        printf("\n");
    
    
    return 0;

【问题讨论】:

您是否尝试调试代码?你为什么把它标记为c++?您至少可以评论您的代码吗?五个嵌套范围可能太多了? 在堆栈上分配高达 1.6 兆字节 (20*20000*sizeof(int)) 的行 int A[T][20000]; 看起来非常危险。您可能需要考虑使用堆来代替,通过使用动态内存分配(例如malloc)。 另请注意,ISO C11 标准不要求支持 variable-length arrays。这意味着您的代码可能无法在某些平台上运行。 你可能想看看 hashmaps 您可以通过交错每个测试用例的输入和输出来减少存储空间,即在打印测试用例 #1 的输出之前不要读取测试用例 #2 的输入。 【参考方案1】:

我花了几天时间,但我终于知道如何做到这一点。显然,它并不像我想象的那么复杂......这是工作代码。感谢所有帮助过的人:)

#include <stdio.h>

int main() 
    int T, N;
    
    scanf("%d", &T);
    
    for (int i = 0; i<T; i++) 
        
        scanf("%d", &N); getchar();
        
        //INPUT elements and counting frequncy for each element
        int f[200001] = 0, E = 0;
        for (int j = 0; j<N; j++) 
            scanf("%d", &E); getchar();
            f[E]++;
        
        
        //find max frequency and how many elements with max frequency
        int max = 0, c = 0;
        for (int j = 1; j<200001; j++) 
            
            if (f[j] == max) 
                c ++;
            
            
            if (f[j]>max) 
                max = f[j];
                c = 1;
            
            
        
        
        //OUTPUT result
        printf("Case #%d: %d\n", i+1, max);
        int counter = 0;
        for (int j = 1; j<200001; j++) 
            if (f[j] == max) 
                
                counter ++;
                if (counter<c)
                    printf("%d ", j);   
                 else 
                    printf("%d\n", j);
                
                
             
        
    
    return 0;

【讨论】:

以上是关于查找数组的最高频率以及具有该频率的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

查找并返回数组中出现频率最高的元素

编写一个算法来查找数组中出现频率最高的元素。给出算法的时间复杂度

确定 vector<char> 中频率最高的 char 元素?

OJ | 力扣347输出前 K 个高频元素

具有相同索引的数组已更改而未重新分配

Java 求解前 K 个高频元素