问题描述:
假如有大数量(百万,千万级....)的人员编号是固定长度的, 我们从中遍历一遍,
取固定长度每位的众数组合出一个编号作为中奖者(并不是等概率)
不考虑该编号是空编号, 假如一位有多个众数取数值最小的那一位
假如下边的几个编号,长度是12位的:
我们取每个字符串的第一位求出众数,作为中奖者编号的第一位, 每个第二位求众数............
该例子的众数编码为:123456789011
思路:
求众数怎么求?统计每一个数出现的次数呗
既然求 固定位的众数, 一个位上数字的范围也就是0-9,无论N多大编号每一位的数字都只是这10个数
我们完全可以做个数组来给每个数出现的次数记数,初始值为0
遍历时第x位的数是y就把数组中第一列的第y行计数器+1
遍历完N个编号再统计数组中每位中出现次数最高的那一个数连起来就是 中奖编号
遍历数组就要做循环, 一层控制读N个编号,一层控制读一个编号每位数,
再利用循环变量来给对应的计数器+1;
程序:
(注释掉的部分可以输出 记数数组, 是个10*N的数组)
package learn;
public class Zhongshu {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] arr;
arr=new int[10][12];//10代表0-9,12代表编码长度
int[] finalarr=new int[12];//记录最终统计结果
String[] str=new String[8]; //8个编号, 每个长度为 12
str[0]="123456789011";
str[1]="761436438941";
str[2]="025824745013";
str[3]="124321456451";
str[4]="323456789010";
str[5]="945645678431";
str[6]="323456789011";
str[7]="145654342381";
for(String s : str)
{
for(int i=0;i<12;i++)
{
arr[s.charAt(i)-'0'][i]++;
}
}
for(int j=0;j<12;j++) //统计表并计算出结果
{
for(int i=0;i<10;i++)
{
if(arr[i][j]>arr[finalarr[j]][j])
finalarr[j]=i;
}
}
// for(int j=0;j<10;j++) //输出统计表
// {
// for(int i=0;i<12;i++)
// {
// System.out.print(arr[j][i]);
// }
// System.out.println(" ");
// }
for (int fi : finalarr)
System.out.print(fi);
}
}
因为编号串只遍历了一次,记数表与N的个数无关,所以时间复杂度是 O(n)级别