算法思想
将大量杂乱数据按照大小顺序排出每个数字重复多少次。通过两个数组实现。原始数据数组a和按照数字大小排出的重复次数数字count。a的数字大小对应count的下标,count下标对应的值是该下标重复出现的次数。用循环遍历统计。
注意
a数组下标从0开始,并且每一个下标位置都有具体的值,count数组下标对应的就是这个数字出现的次数,如果限定了count的大小范围,则不用从0开始考虑
代码针对一个具体问题:假设一个公司有一万个员工,年龄集中在21~60岁,要统计出最年轻的一千名员工的平均年龄
在计算前一千名员工平均年龄的时候,不是一下子找出这一千个人计算平均年龄的(实际上也办不到),而是拆解成一步一步的去算,每一步都算出一个平均数,下一次用这个平均数来算出总数,保证最后恰好统计到1000个人。
代码实现
代码(疯狂注释版)
加了很多print用来测试写的对不对,小白第一次用rand()生成限定范围的值,后来都注释掉了,只留了最后用来统计的count数组。
#include <iostream>
#include<malloc.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
//HashSort
// 时间复杂度:O(n)
//算法思想:很多数据的情况下要统计部分数据有多少、平均值等,初始化一个数组,每次遇到对应数组序号的值
//则对应序号的数组值+1,这样就能统计出每个值有多少个数字
//即:数组下标是数字的值,数组的值是数字出现的次数
int main()
{
//随机生成一万个年龄在21-60岁的员工年龄(整数),使用rand()产生随机数。
//要随机数在21-60之间,则用随机数对40取余,会产生0-39之间的数,之后加上21,则产生21~60之间的数
//伪随机数,只是为了方便用了rand(),不是真正的随机数
int a[10000];//年龄数组,共一万个随机年龄
for (int i = 0; i < 10000; i++)
{
a[i] = rand() % 40 + 21;
}
//打印部分年龄测试
/*for (int x = 0; x < 100; x++)
{
cout << a[x] << " ";
}*/
cout << endl;
//年龄人数数组初始化,设置61个值可以使下标从0~60,共61个数
int count[61] = { 0 };
//遍历年龄数组,每遇到一个年龄,则对应人数数组下标位置的值++
for (int j = 0; j < 10000; j++)
{
count[a[j]]++;
}
//打印出年龄人数数组
for (int y = 21; y < 61; y++)
{
cout << y << "岁: " << count[y] << " ";
}
/*//验算最后是不是10000人的数据
int sum = 0;
for (int n = 0; n < 61; n++)
sum += count[n];
cout << endl;
cout << sum;
*/
//不能一次直接找到前一千个人,所以循环遍历,分为两种情况:
//1.加上某个年龄的人数后正好是一千人;2.加上某个年龄的人数后超过一千人,只取这里人数的一部分算
// 一定只有这两种情况,要么加上下一个年龄段的人数不足或正好够了,要么加上后人数直接超了
//核心想法:不是一次性找出前一千人是谁和算出平均值的,而是分步,每一步都算出一个平均值,用于计算加上下一个年龄人的人数后的平均值
int num = 0;
float average = 0;//平均年龄
for (int z = 21; (z < 61) && (num < 1000); z++)
{
if (num + count[z] <= 1000)
{
//当前人数加上这个年龄段人数小于等于1000则这个年龄段人全部都加上算平均
average = (average * num + z * count[z]) / (num + count[z]);
num += count[z];
}
else
{
//当前人数加上这个年龄段人数大于1000则计算还差多少人满1000,缺的人数用当前年龄补上
average = (average * num + (1000 - num) * z) / 1000;
num = 1000;
}
}
cout << "\n\n —————————————— \n\n" << "人数: " << num << " 平均年龄: " << average << endl;
}
代码(纯享版)
#include <iostream>
#include<malloc.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main()
{
int a[10000];//年龄数组,共一万个随机年龄
for (int i = 0; i < 10000; i++)
{
a[i] = rand() % 40 + 21;
}
int count[61] = { 0 };
for (int j = 0; j < 10000; j++)
{
count[a[j]]++;
}
//打印出年龄人数数组
for (int y = 21; y < 61; y++)
{
cout << y << "岁: " << count[y] << " ";
}
int num = 0;
float average = 0;//平均年龄
for (int z = 21; (z < 61) && (num < 1000); z++)
{
if (num + count[z] <= 1000)
{
average = (average * num + z * count[z]) / (num + count[z]);
num += count[z];
}
else
{
average = (average * num + (1000 - num) * z) / 1000;
num = 1000;
}
}
cout << "\n\n —————————————— \n\n" << "人数: " << num << " 平均年龄: " << average << endl;
}