位图排序算法的一个实践

适应场景:
1,输入的数据限制在相对较小的范围内;2,数据没有重复;3,对于每条记录而言,除了单一整数外,没有任何其他相关联的数据。

2,要求
输入:一个最多包含n个正整数的文件F1,每个数小于n(n=1000000),而且整数没有重复;
输出:包含按升序排列的整数列表的文件F2;
约束:不超过1M的内存空间,运行时间10秒以内。

3,实现概要
可以用一个20位长度的0,1字符串来表示所有元素小于20的非负整数的集合。比如可以用下面的字符串来标示集合{1,2,3,5,8,13}:
S={0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 }
即S[1],S[2],S[3],S[5],S[8],S[13]都是1,其他的都是0.

利用上面的思想,可以用一个长度为n的字符串来表示文件F1里面的整数集合,然后遍历这个字符串,如果为1则输出下标的文件F2.
伪代码:
//初始化
for i=[0,n)
bit[i]=0;
//扫描输入文件
for each i in F1
bit[i]=1;
//输出
for each i=[0,n)
if bit[i]==1
write i to F2

我用java做了这个算法的实践,bit 数组采用的是JDK里面的BitSet,代码如下:
[code]

public static void main(String[] args) throws IOException {
int n = 10000000;
int k = 1000000;
String srcFile = "/tmp/in.dat";
String destFile = "/tmp/out.dat";
long start = System.currentTimeMillis();
genRandomNumbers2File(srcFile, n, k);
sortAndSave2File(srcFile, destFile, n);
long end = System.currentTimeMillis();
System.out.println("Done in " + (end - start) + " ms");
}

/**
* 在文件fileName中生成一个所有元素互异且位于[0,n)之间的随机排列的整数序列,序列长度为k
*
* @param fileName
* @param n
* @param k
* @throws IOException
*/
public static void genRandomNumbers2File(String fileName, int n, int k)
throws IOException {
File f = new File(fileName);
if (!f.exists()) {
f.createNewFile();
}
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(f));
int[] array = new int[n];// 定义初始数组
for (int i = 0; i < n; i++)
array[i] = i;
Random random = new Random();
for (int j = 0; j < k; j++) {
int index = j + random.nextInt(n - j);// 生成一个[j,n)之间的随机数,作为数组下标
// 交换array[j]和array[index],那么array[0..j]为已经获取到的随机数
int temp = array[index];
array[index] = array[j];
array[j] = temp;
// 把此次获取到的随机数存到rets里面
bos.write(temp);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos != null) {
bos.close();
}
}
}
//从文件srcFile读取整数序列然后排序,并写到的destFile中
public static void sortAndSave2File(String srcFile, String destFile, int n)
throws IOException {
File fsrc = new File(srcFile);
File fdest = new File(destFile);
if (!fdest.exists()) {
fdest.createNewFile();
}
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(fsrc));
BitSet bs = new BitSet(n);
int read = 0;
while ((read = bis.read()) != -1) {
bs.set(read);
}
//
bos = new BufferedOutputStream(new FileOutputStream(fdest));
for (int i = 0; i < n; i++) {
if (bs.get(i)) {
// System.out.println(i);
bos.write(i);
}
}

} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos != null) {
bos.close();
}
if (bis != null) {
bis.close();
}
}
}
[/code]

此博客的算法思想来源于《编程珠玑(第二版)》第一章
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值