在大容量数据集中查找前N个数的算法
2008-10-26 20:16
393 查看
因工作原因,前阵子看了MTK中关于FM搜频的代码,其中记忆犹新的是一种比较实用的查找算法,我依据它的思想对这个算法做了小小的改动。
该算法的作用是在容量加大的数据集中查找前N个最大(也可以是最小,最大和最小不是算法的关键)数字,当然,这里的N一般比较小,如在100,000,000个数中查找前10个最大的数字。传统的算法是先对这100万个数排序,再取前10个,但对这么多的数字排序相当慢,由于只需取10个数,其余数字的排序实际上是无用的,因此需要一种新的算法。下面简述本文所说的算法思路:
该算法的思路是:每次在所有数据集中选出最大的数字,并将该数字设置一个标志位,已免下次遍历最大值的时候重复选中该数字。为避免查找算法的额外开销,设置标志位的方法比较重要,如果这些数据全部是整数,我们可以用位运算处理;如果是浮点数,我们可以先将这些数据放大,在一定精度范围内将其转化为整数,再使用位运算处理(当然,应该有其他的处理方式)。
写了这么多,个人觉得还是通过程序看算法容易得多。为获取大量不同数据源,我采用随机数生成了10000个整数,并在这些数字中选前10个数字。
/***************************************************
* Name: Rapid Searching Arithmetic
*
* Author: zhouliang
* Date: 2008-10-20
* Email: zhouliang531@163.com
**************************************************/
#include "stdlib.h"
#include "stdio.h"
#include "time.h"
#define MAX_BIT 0x8000 /*屏蔽的最大比特位,也可以是0x40, 0x800等*/
#define MARK(x) ((x) |= MAX_BIT) /*即(x) | = 0x8000*/
#define IS_MARK(x) ((x) & MAX_BIT) /*即(x) & 0x8000*/
#define UNMARK(x) ((x) & (MAX_BIT-1)) /*即(x) | 0x7FFF*/
#define MAX_DATA (MAX_BIT - 1) /*即0x7FFF*/
#define TOP_NUM 10 /*找出前N个最大值*/
#define TOTAL_NUM 10000 /*总个数*/
void main( void )
{
int i, j;
int data[TOTAL_NUM]; /*存储所有数据*/
int result[TOP_NUM]; /*存储查找结果*/
int max, temp;
int index;
/*确保总个数不小于TOP个数*/
if (TOP_NUM > TOTAL_NUM){
printf("Please make sure TOP_NUM <= TOTAL_NUM");
return;
}
/*以时间为种子,生成随机数*/
srand( (unsigned)time( NULL ) );
/* 生成 TOTAL_NUM个小于MAX_DATA的随机数*/
for (i=0; i<TOTAL_NUM; i++){
do {
temp = rand();
}while(temp > MAX_DATA);
data[i] =temp;
printf("%6d/n", temp);
}
/*查找最大的TOP_NUM个数字*/
for (i=0; i<TOP_NUM; i++){
max = 0;
index = -1;
for (j=0; j<TOTAL_NUM; j++){
if (!IS_MARK(data[j])){ /*避免重复选取*/
temp = UNMARK(data[j]);
if (temp > max){
max = temp;
index = j;
}
}//end if
}//end for
if (index >= 0){ /*找到最大的,标记*/
result[i] = data[index];
MARK(data[index]);
}
else{
break;
}
}//end for
printf("Top %d Number:/n", TOP_NUM);
for (i=0; i<TOP_NUM; i++){
printf("%6d/n", result[i]);
}
} // end main
为测试数据集多变,上述程序通过时间种子生成随机数,因此每次运行的时候可以得到不同的数据集。
该算法的作用是在容量加大的数据集中查找前N个最大(也可以是最小,最大和最小不是算法的关键)数字,当然,这里的N一般比较小,如在100,000,000个数中查找前10个最大的数字。传统的算法是先对这100万个数排序,再取前10个,但对这么多的数字排序相当慢,由于只需取10个数,其余数字的排序实际上是无用的,因此需要一种新的算法。下面简述本文所说的算法思路:
该算法的思路是:每次在所有数据集中选出最大的数字,并将该数字设置一个标志位,已免下次遍历最大值的时候重复选中该数字。为避免查找算法的额外开销,设置标志位的方法比较重要,如果这些数据全部是整数,我们可以用位运算处理;如果是浮点数,我们可以先将这些数据放大,在一定精度范围内将其转化为整数,再使用位运算处理(当然,应该有其他的处理方式)。
写了这么多,个人觉得还是通过程序看算法容易得多。为获取大量不同数据源,我采用随机数生成了10000个整数,并在这些数字中选前10个数字。
/***************************************************
* Name: Rapid Searching Arithmetic
*
* Author: zhouliang
* Date: 2008-10-20
* Email: zhouliang531@163.com
**************************************************/
#include "stdlib.h"
#include "stdio.h"
#include "time.h"
#define MAX_BIT 0x8000 /*屏蔽的最大比特位,也可以是0x40, 0x800等*/
#define MARK(x) ((x) |= MAX_BIT) /*即(x) | = 0x8000*/
#define IS_MARK(x) ((x) & MAX_BIT) /*即(x) & 0x8000*/
#define UNMARK(x) ((x) & (MAX_BIT-1)) /*即(x) | 0x7FFF*/
#define MAX_DATA (MAX_BIT - 1) /*即0x7FFF*/
#define TOP_NUM 10 /*找出前N个最大值*/
#define TOTAL_NUM 10000 /*总个数*/
void main( void )
{
int i, j;
int data[TOTAL_NUM]; /*存储所有数据*/
int result[TOP_NUM]; /*存储查找结果*/
int max, temp;
int index;
/*确保总个数不小于TOP个数*/
if (TOP_NUM > TOTAL_NUM){
printf("Please make sure TOP_NUM <= TOTAL_NUM");
return;
}
/*以时间为种子,生成随机数*/
srand( (unsigned)time( NULL ) );
/* 生成 TOTAL_NUM个小于MAX_DATA的随机数*/
for (i=0; i<TOTAL_NUM; i++){
do {
temp = rand();
}while(temp > MAX_DATA);
data[i] =temp;
printf("%6d/n", temp);
}
/*查找最大的TOP_NUM个数字*/
for (i=0; i<TOP_NUM; i++){
max = 0;
index = -1;
for (j=0; j<TOTAL_NUM; j++){
if (!IS_MARK(data[j])){ /*避免重复选取*/
temp = UNMARK(data[j]);
if (temp > max){
max = temp;
index = j;
}
}//end if
}//end for
if (index >= 0){ /*找到最大的,标记*/
result[i] = data[index];
MARK(data[index]);
}
else{
break;
}
}//end for
printf("Top %d Number:/n", TOP_NUM);
for (i=0; i<TOP_NUM; i++){
printf("%6d/n", result[i]);
}
} // end main
为测试数据集多变,上述程序通过时间种子生成随机数,因此每次运行的时候可以得到不同的数据集。
相关文章推荐
- 在大容量数据集中查找前N个数的算法
- 实现了一个压缩算法,在数据高度压缩的前提下,还可以快速查找 key
- 【数据结构作业二】写出单链表结点的结构体类型定义及查找、插入、删除算法,并以单链表作存储结构,实现有序表的合并
- 算法:查找int数组中重复的数据
- Java数据结构与算法之【二分查找】
- 查找正序排列的List中缺失的日期数据的一个算法
- 挖掘DBLP作者合作关系,FP-Growth算法实践(1):从DBLP数据集中提取目标信息(会议、作者等)
- 数据查找算法---顺序查找、二分法查找、二叉树查找、hash查找
- 数据结构算法学习-1. 查找(Search)概论与三种顺序查找算法
- #数据结构与算法学习笔记#剑指Offer1.5:二维数组中的查找(C++)
- 实现了一个压缩算法,在数据高度压缩的前提下,还可以快速查找 key
- 数据结构与算法题目集(中文)4-10 二分查找 (20分)
- 【数据结构与算法】【查找】哈希表的代码实现
- 常用查找数据结构及算法(Python实现)
- 算法题41 超大数据量遍历查找
- 详解常用查找数据结构及算法(Python实现)
- 【数据结构与算法】二分查找
- 数据结构之算法2.6-在顺序线性表L中查找第1个值与e满足compare()的元素的位序
- 数据结构——算法之(019)( 10分钟写出二分法查找,并调试通过)
- 算法研究:如何将数组中的重复数据查找出来