算法实现题 2-2 众数问题

问题描述:

给定含有 n 个元素的多重集合 S,每个元素在 S 中出现的次数称为该元素的重数。多重集 S 中重数最大的元素称为众数。例如,S={1,2,2,2,3,5}。多重集 S 的众数是 2,其重数为 3。

编程任务:

对于给定的由 n 个自然数组成的多重集 S,编程计算 S 的众数及其重数。

数据输入:

输入数据由文件名为 input.txt 的文本文件提供。

文件的第 1 行多重集 S 中元素个数 n;接下来的 n 行中,每行有一个自然数。

结果输出:

程序运行结束时,将计算结果输出到文件 output.txt 中。输出文件有 2 行,第 1 行给

出众数,第 2 行是重数。

输入文件示例

input.txt
6
1
2
2
2
3
5

输出文件示例

output.txt
2
3

思路:

  1. 排序
  2. 二分法 找出 middle的个数
  3. 递归找左边数 middle的个数,和右边数middle的个数
  4. 找众数以及个数

代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>

using namespace std;


class File
{
public :
    vector<int> getNum (string path)
    {
        FILE *f=fopen(path.c_str(),"r");
        vector<int> ve;
        int num;
        while(fscanf(f,"%d",&num)!=EOF)
        {
            ve.push_back(num);
        }
        fclose(f);
        return ve;
    }
    vector<int> answer(string path)
    {
        FILE *f=fopen(path.c_str(),"r");
        vector<int> ve;
        int num;
        while(fscanf(f,"%d",&num)!=EOF)
        {
            ve.push_back(num);
        }
        fclose(f);
        return ve;
    }
    bool compare(vector<int>ve,int a[],int N)
    {
        for(int i=0; i<N; i++)
        {
            if(a[i]!=ve[i])
                return false;
        }
        return true;
    }
};
void  func(vector<int> ve,int l,int r,int &count,int &number)
{
    if(l>r)
        return ;
    int ll=0,rr=0;
    int mid=(l+r)/2;
    while((mid-ll>=l)&&(ve[mid-ll]==ve[mid]))
    {
        ll++;
    }
    while((mid+rr<=r)&&(ve[mid+rr]==ve[mid]))
    {
        rr++;
    }
    int c=ll+rr-1;
    if(count<=c)
    {
        count=c;
        number=ve[mid];
    }
    if(mid-ll+1>=count)
            func(ve,mid+rr,r,count,number);
    if(r-mid-rr+1>=count)
            func(ve,l,mid-ll,count,number);




}
int main()
{
    File f;
    bool temp=true;
    int count;
    for(int k=1;k<=10;k++)
    {

        vector<int> ve=f.getNum("F:\\算法\\实验组2-分治-实验包\\prog21\\test\\mode"+to_string(k)+".in");
        int n=ve[0];
        sort(ve.begin()+1,ve.end());
        count=0;
        int number=0;

        func(ve,1,n-2,count,number);

        int an[2];
        an[0]=number;
        an[1]=count;

        vector<int> ve2;
        ve2=f.answer("F:\\算法\\实验组2-分治-实验包\\prog21\\answer\\mode"+to_string(k)+".out");

        bool flag=true;
        flag=f.compare(ve2,an,2);
        if(!flag)
        {
            cout << "第" << k << "个测试用例未通过" << endl;
            temp=false;
        }
        else
            cout << "第" << k << "个测试用例通过" << endl;
        ve.clear();
        ve2.clear();

    }
    if(temp)
        cout << "测试用例全部通过" << endl;

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是我为您准备的100道Java算法: 1. 翻转字符串 2. 在数组查找重复数字 3. 单例模式 4. 冒泡排序 5. 快速排序 6. 选择排序 7. 插入排序 8. 希尔排序 9. 归并排序 10. 桶排序 11. 堆排序 12. 计数排序 13. 二叉树的遍历 14. 二叉树的深度 15. 二叉树的最大深度 16. 二叉树的最小深度 17. 二叉树的最大宽度 18. 二叉树的节点个数 19. 二叉树的叶子节点个数 20. 二叉树的高度 21. 二叉树的镜像 22. 二叉树的序遍历 23. 二叉树的前序遍历 24. 二叉树的后序遍历 25. 二叉树的层次遍历 26. 二叉树的层次遍历 II 27. 二叉树的锯齿形层次遍历 28. 二叉树的最近公共祖先 29. 二叉树的路径和 30. 二叉树的路径和 II 31. 二叉树的所有路径 32. 二叉树的所有路径 II 33. 二叉树的最长连续序列 34. 二叉树的最深叶子节点的最近公共祖先 35. 二叉树的最大路径和 36. 二叉树的最小深度 II 37. 二叉树的右视图 38. 二分查找 39. 二分查找的变体 40. 二叉搜索树的插入 41. 二叉搜索树的删除 42. 两数之和 43. 三数之和 44. 四数之和 45. 无重复字符的最长子串 46. 最长回文子串 47. 最长公共前缀 48. 字符串的第一个唯一字符 49. 罗马数字转整数 50. 整数转罗马数字 51. 最大子序和 52. 最长上升子序列 53. 最长公共子序列 54. 最长回文子序列 55. 编辑距离 56. 最长有效括号 57. 最长公共子串 58. 最长连续递增序列 59. 最长连续递减序列 60. 最长连续重复子串 61. 最长重复子数组 62. 最短无序连续子数组 63. 最长的斐波那契子序列的长度 64. 最长等差数列 65. 最长连续子序列 66. 最长湍流子数组 67. 最长子数组的和 68. 最小覆盖子串 69. 最小路径和 70. 最小栈 71. 最大栈 72. 最小栈和最大栈的实现 73. 最小栈和最大栈的查找 74. 最小栈和最大栈的删除 75. 最小栈和最大栈的修改 76. 最小栈和最大栈的插入 77. 最小栈和最大栈的求和 78. 最小栈和最大栈的求差 79. 最小栈和最大栈的求积 80. 最小栈和最大栈的求商 81. 最小栈和最大栈的求余 82. 最小栈和最大栈的排序 83. 最小栈和最大栈的反转 84. 最小栈和最大栈的合并 85. 最小栈和最大栈的交集 86. 最小栈和最大栈的并集 87. 最小栈和最大栈的差集 88. 最小栈和最大栈的对称差 89. 最小栈和最大栈的求最大值 90. 最小栈和最大栈的求最小值 91. 最小栈和最大栈的求位数 92. 最小栈和最大栈的求平均值 93. 最小栈和最大栈的求方差 94. 最小栈和最大栈的求标准差 95. 最小栈和最大栈的求众数 96. 最小栈和最大栈的求众数 II 97. 最小栈和最大栈的求众数 III 98. 最小栈和最大栈的求众数 IV 99. 最小栈和最大栈的求众数 V 100. 最小栈和最大栈的求众数 VI 希望这些算法能够对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值