众数的求法

★问题描述:
给定含有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       output.txt
6              2
1              3
2
2
2
3

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

1、数组的众数求法

这回是对上次发帖后改用分治法解决的,还有待改进之处。

  1. #include<iostream>
  2. #include<fstream>
  3. using namespace std;
  4. //结构体用来保存众数的元素与重数
  5. typedef struct
  6. {
  7. int element;//元素
  8. int sum;//重数
  9. }zs;
  10. //记录中位数的起始下标
  11. typedef struct
  12. {
  13. int low;
  14. int high;
  15. }node;
  16. //快排
  17. zs x;
  18. //int data=1;
  19. void sort(int a[],int s,int t)//对a[s]到a[t]的元素排序
  20. {
  21. int i=s,j=t;
  22. int temp;
  23. if(s<t)//区间里至少存在一个元素的情况
  24. {
  25. temp=a[s];//用区间的第一个元素做基准
  26. while(i!=j)//区间两端交替向中间扫描,知道I=J
  27. {
  28. while(j>i&&a[j]>temp)
  29. j--;//从右向左扫描,找到第一个小于temp的a[j]
  30. if(i<j)//表示找到a[j],则a[i],a[j]交换
  31. {
  32. a[i]=a[j];
  33. i++;
  34. }
  35. while(i<j&&a[i]<temp)
  36. i++;//从左向右扫描,找到第一个大于temp的a[i]
  37. if(i<j)//表示找到a[i],则a[i],a[j]交换
  38. {
  39. a[j]=a[i];
  40. j--;
  41. }
  42. }
  43. a[i]=temp;
  44. sort(a,s,i-1);//对左递归
  45. sort(a,i+1,t);//对右递归
  46. }
  47. }
  48. //中位数
  49. int madian(int *a,int l,int r)
  50. {
  51. int x=r+l+1;
  52. //  if(x%2)
  53. return a[x/2];//为奇数时
  54. //  else
  55. //      return (a[x/2]+a[x/2+1])/2;//为偶数时
  56. }
  57. //返回中位数的起始点
  58. node spalit(int *a,int med,int l,int r)
  59. {
  60. node m;
  61. m.low=l;m.high=r;
  62. for(int i=0;i<=r;i++)
  63. {
  64. if(med==a[i])
  65. {
  66. m.low=i;
  67. break;
  68. }
  69. }
  70. for(int j=r;j>=0;j--)
  71. {
  72. if(med==a[j])
  73. {
  74. m.high=j;
  75. break;
  76. }
  77. }
  78. return m;
  79. }
  80. //众数的重数求取
  81. void mode(int *a,int l,int r)
  82. {
  83. if(l>=r)return;
  84. //x.sum=0;
  85. else
  86. {
  87. node n;
  88. int temp=0;
  89. int med;
  90. med=madian(a,l,r);
  91. n=spalit(a,med,l,r);
  92. temp=n.high-n.low+1;
  93. if(x.sum<temp)
  94. {
  95. x.element=med;
  96. x.sum=temp;
  97. }
  98. if(n.low-l>temp)//
  99. {
  100. if(x.sum<temp)
  101. {
  102. x.element=med;
  103. x.sum=temp;
  104. }
  105. mode(a,l,n.low-1);
  106. }
  107. if(r-n.high>temp)
  108. {
  109. if(x.sum<temp)
  110. {
  111. x.element=med;
  112. x.sum=temp;
  113. }
  114. mode(a,n.high+1,r);
  115. }
  116. }
  117. }
  118. void main()
  119. {
  120. x.sum=0;
  121. int n;
  122. int *a;
  123. ifstream in("C://inputdate.txt");
  124. if(!in)
  125. {
  126. cout<<"the file can‘t open!"<<endl;
  127. }
  128. in>>n;
  129. a=new int[n];
  130. for(int i=0;i<n;i++)
  131. {
  132. in>>a[i];
  133. }
  134. sort(a,0,n-1);
  135. mode(a,0,n-1);
  136. cout<<x.element<<" "<<x.sum<<endl;
  137. delete []a;
  138. }

第二种

void mode(int l,int r){

int l1,r1;

int med=median(a,l,r);

split(a,med,l,r,l1,r1);

if(largest<r1-l1+1){

largest=r1-l1+1;

element=med;

}

if(l1-1>largest)

mode(1,l1-1);

if(r-r1>largest)

mode(r1+1,r);

}

3、利用先排序,然后统计个数。考虑时间效率,采用快排,count (统计个数),maxCount(最多的个数),element(重数最大的数即众数)

4.可以利用散列法。

时间: 2024-10-14 10:36:46

众数的求法的相关文章

CSP2019考前错误总结

11.9 取模要尽量多取模,遇到减号要先加再取模. 神奇的性质题. 11.8 stl的使用不够熟练,暴力分拿的不如别人高. t3没有时间把暴力打完.t3暴力卡常还能AC. 概率期望是大坑. 11.7 暴力分都拿到了.但一定要尽力想正解,暴力只是迫不得已. 其实t2的dp还是很容易想...但考试时想不出来的情况要反思. 文件错误...一定要高度重视. 11.6 注意看数据范围.无法保证正确性时一定要用数据分治. 线段树合并忘记了. 11.5 T1找规律的题思维还不够,只会打暴力dp. 输出时要检查

对于一遍遍历的众数求法

日期:2019.6.3 博客期:073 星期日 或许你在想求众数的基本方法: 遍历一遍找到每个数的出现次数,之后找到次数最多的那个! 经过我们的分析,可知这个实际上是在遍历过程中,找到次数最多的数!那我们就可以采取记录次数的方法! 1 package test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import my.javabean.basic.*; 7 import my.javabean.file.Fil

众数问题

描述 所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数, 多重集合S重的重数最大的元素成为众数.例如:S={1,2,2,2,3,5},则多重集S的众数是2,其重数为3. 现在你的任务是:对于给定的由m个自然数组成的多重集S,计算出S的众数及其重数. 输入 第一行为n,表示测试数据组数.(n<30) 每组测试的第一行是一个整数m,表示多重集S中元素的个数为m 接下来的一行中给出m(m<100)个不大于10万的自然数 (不会出现不同元素出现的次数相同的情

POJ 2478 欧拉函数(欧拉筛法) HDU 1576 逆元求法

相关逆元求法,我之前有写过,还有欧拉函数的求法,欧拉函数与逆元的关系  点击 POJ 2478 又是一个打表的题目,一眼看出结果就是前n个欧拉函数值的和. 这里直接计算欧拉函数值求和会超时,看见多组数据. 然后就是计算欧拉函数,打表就好了. #include <stdio.h> #include <string.h> #include <iostream> using namespace std; typedef long long LL; const int N =

逆元以及线性逆元求法(转)

对于一个数a,如果a*a^-1=1(modp),那么a^-1是a对于p的逆元 在除法中,除以一个数等于乘上这个数的逆元,即x/y=x*y^-1(modp) 求单个逆元可以用费尔马小定理 对于质数p,a^(p-1)=1(modp),那么a^(p-2)*a=a^(p-1)=1(modp),所以a^-1=a^(p-2),用快速幂求即可 但对于一堆数,例如1~n一一求逆元,用快速幂是O(nlogn)的,若n达到1e7会爆炸,所以需要线性求逆元的方法 假设当前要求数i的逆元,且1~i-1的逆元都已经求好了

众数问题(山东理工OJ)

题目描写叙述 给定含有n个元素的多重集合S,每一个元素在S中出现的次数称为该元素的重数.多重集S中重数最大的元素称为众数. 比如,S={1,2,2,2,3.5}.多重集S的众数是2,其重数为3. 对于给定的由n 个自然数组成的多重集S.计算S的众数及其重数. 输入 输入数据的第1行是多重集S中元素个数n(n<1300000):接下来的n行中,每行有一个最多含有5位数字的自然数,. 输出 输出数据的第1行给出众数,第2行是重数. 演示样例输入 6 1 2 2 2 3 5 演示样例输出 2 3 #i

【基础备忘】 二叉树前序、中序、后序遍历相互求法

转自:http://www.cnblogs.com/fzhe/archive/2013/01/07/2849040.html 今天来总结下二叉树前序.中序.后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出,下面我们分别说明. 首先,我们看看前序.中序.后序遍历的特性: 前序遍历:     1.访问根节点     2.前序遍历左子树     3.前序遍历右子树 中序遍历:     1.中序遍历左子树     2

强连通分量的三个求法

这里主要谈及强连通分量(以下简称SCC,strongly connected component)三种常见的求法(以下涉及的图均为有向图),即Kosaraju.Tarjan和Gabow.三种算法背后的基础思想都是DFS,只是它们通过DFS获得了不同的信息.各位大哥大姐继续往下读之前,最好对DFS相关的概念和性质比较熟悉,例如,什么叫做<a title="DFS" href="http://en.wikipedia.org/wiki/Depth-firstsearch&q

二叉树前序、中序、后序遍历相互求法

今天来总结下二叉树前序.中序.后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出,下面我们分别说明. 首先,我们看看前序.中序.后序遍历的特性: 前序遍历:     1.访问根节点     2.前序遍历左子树     3.前序遍历右子树 中序遍历:     1.中序遍历左子树     2.访问根节点     3.中序遍历右子树 后序遍历:     1.后序遍历左子树     2.后序遍历右子树     3.访问