12.5 制作素数表

可以利用筛法求出并制作素数表。问题在于在代码中可以使用的内存空间是有限的,在函数内可以使用的内存空间就更有限。

尽管在前文中采用了一种压缩数据的方法,使得得到一张较大的素数表成为可能,然而由于函数内可以使用的内存有限,这种方法的改进效果也非常有限(把素数表扩大了8倍)。

下面例题中,使用磁盘文件作为素数表的存储空间,可以求得更大的素数表。由于题目的目的只是演示文件的使用及在这种条件下的算法,所以没有采用程序代码8-13的表示模型,因为那样将使代码更为复杂。本例题中只简单地用字节在文件中的位置表示一个自然数,用这个字节的值为'F'表示相对应的数不是素数,如果为'S'则表示对应的数是素数。

首先建立一个文件,大小为216-1字节,并将各个字节都写为'S',以表示最初无法确定哪些正整数不是素数(由函数调用“xiewenjian(pf, SUSHU, SEEK_SET, ZUIDASHU, 1L);”实现)。

然后把第一个字节改写为'F',因为1明显不是素数。

接着从头到尾检查哪些字节为'S',一旦遇到表示素数的字节,则把这个数的整数倍都“筛掉”。

事实上不需要一直检查到最后,只要把前12.5 制作素数表 - 图1个数中素数的倍数筛掉就可以了。在求12.5 制作素数表 - 图2时应用了函数原型写在“math.h”中的求平方根近似值的函数,并考虑了可能产生的误差。

最后根据“sushubiao”文件中的内容,得到了一个“sushubiao.txt”文本文件,以文本的方式写出了1~USHRT_MAX之间所有素数从小到大排列的素数表。

程序代码12-7

12.5 制作素数表 - 图3

12.5 制作素数表 - 图4

12.5 制作素数表 - 图5

12.5 制作素数表 - 图6

12.5 制作素数表 - 图7

出于篇幅和易于阅读方面的考虑,这里的代码没有写完全(数据错误处理部分)。但值得注意的是,在文件操作中,很容易发生各种各样的错误,比如磁盘空间不足、磁盘写保护等,因此在写代码时应该充分考虑到这些情况,否则程序只能在很理想的环境中运行,一旦有点风吹草动很容易崩溃。