[ ]内的为书上的内容:[
例8-2 用筛选法求1000已内的素数。
用一个集合s作筛子,首先把2..1000全部放入筛子s内,再用一个变量v记录当前处理的(筛的)数据;然后使v从2开始逐步增加,对每个v都将v的倍数从筛s中筛掉;最后当v变到1000/2时,在筛s内剩余的便全部是素数了。按该思想算法程序如下:
const m = 1000;
type tyset = set of 2..m;
procedure prime(var s: tyset);
var v: 2..m;
begin
  s := [2..m];
  for v := 2 to m div 2 do
    if v in s then 
      for i := 2 to m div v do s := s - [i * v];
end;
]  大家别笑我(我很菜),当我刚看完这个程序的时候感觉这个算法不错。
  N天之后我想将书中一些有用的程序输入到电脑中保存起来,翻到此处才发现了type tyset = set of 2..m。我记得集合类型的范围是0..255。我倒,这个程序根本无法运行!
  最害人的是整本书中没有提“集合类型的范围是0..255”。
  我想,我应该谴责这本书的作者,所有买这本书的人都应该谴责他,这个不负责任的家伙!★问题: 
1、我写了一个过程求m到n之间的所有素数,请大家看看有没有毛病?2、还有一个问题:2是不是素数?(我记不清了,我这里当作是了)procedure PrintSuShu(n: integer; m: integer = 2);  //打印m到n之间的所有素数
var
  i,k: integer;
  f: text;
begin
  {为了简单起见,这里没有对n和m的值进行错误检查,实际使用时应该加上。}
  Assign(f,'sushu.txt');
  try
    ReWrite(f);
    for i := n downto m do
    begin
      for k := i - 1 downto 1 do
      begin
        if k = 1 then
        begin
          Write(f,i:5);
          Break;
        end;
        if i mod k = 0 then Break;
      end;
    end;
    Write('已经将结果输出到sushu.txt文件中。');
    ReadLn;ReadLn;
  finally
    CloseFile(f);
  end;
end;★问题:  
3、但是,我由此想到了集合类型的限制,为何要有此限制呢?4、如何突破此限制,从而实现用筛选法求1000以内的素数呢?5、难道集合类型真的不行吗?(不爽!)6、可不可以用其它类型来实现筛选法?7、就算是书上的例子中算的是2到255中的素数,又怎么能把筛选后的集合中的内容输出呢?8、怎么知道筛选后的集合中有多少个元素?有没有相应的通用的函数能够直接求得?这是我想请教大家的!请在每条问题下面的空行处逐条回复,谢谢了!
---------------------------------------------------------

解决方案 »

  1.   

    to:westfly(西翔) 给个具体的例子啊!谢谢了!
    --------------------------------------------
    大家看好了,一共8个问题呢!!
      

  2.   

    集合类型的范围是指定序数类型的幂集所谓幂集,就是给定元素范围,可能构成的所有集合的集合。如,对于集合[1, 2, 3, 4],其幂集是[[], [1], [2], [3], [4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]如果用M表示该幂集,对于下面的声明S: set of 1..4;那么,S的范围是M。Object Pascal规定集合的基类型可能的值不能超过256个并且序号必需在0到255之间,这同时也表明,集合中元素的个数最多是256个;给定了声明的集合,如果最大元素个数为n,那么该集合的范围是2^n个不同集合,包括空集在内。
    ————————————————————————————————————————看了你的贴子,又翻了翻书,果然发现这些以前根本没注意的东西,
    这个玩艺我也不知是不是这个原因,但是感觉是象那么回事, 2^255是多少?:-)
      

  3.   

    但是这个又奇怪了
    我sizeof(S)一下,结果是1,他娘的
    不明白了,那个幂集与内存分配无关?
    娘的,关注!!!
      

  4.   

    --------------------------------------------
    大家看好了,一共8个问题呢!!
    --------------------------------------------
    难道没人想谴责这本书的作者?myling(阿德) 都关注了, 我更关注。
      

  5.   

    1、你的程序是否有毛病,运行检测就可以了。俺不想看代码,因此不知道。2、俺记得还算清楚,2是素数。3、集合类型的内存管理在Object Pascal规定如下:
    一个集合就是一个比特数组,该数组中的每个比特位表示一个元素是否在集合中。集合元素的最大数量是256,因此一个集合占用的空间不可能超过32个字节。指定集合占用的字节数等价于
    (Max div 8) - (Min div 8) + 1
    这里的Max和Min分别是集合基类型的上界和下界。指定元素E的字节编码是
    (E div 8) - (Min div 8)
    并且元素E在该字节中的位(比特)编号是
    E mod 8
    这里,E表示的是元素的序数值。如果可能,编译器在CPU寄存器中存储集合,但如果集合大于一般的Integer类型,或者如果程序中包含了操作集合地址的代码,那么集合总是驻留在内存中。4、俺以为用数组比用集合更合适。因为这里根本不涉及集合的子集特性,纯粹就是为了保存数据。5、用集合来实现筛选法求1000以内的素数,至少不是Pascal能胜任的,不知道以前俺用过的Fortran、Prolog是否能行。明摆着最合适的就是数组,楼上也有人推荐用链表或者TList,何必较劲呢?不客气地说,用集合来解决这样的问题(试图建立大于256的集合),不是欠考虑就是猪脑。6、前面说过了,可用的数据类型很多。如果你不介意,甚至可以用string类型。只要是动态分配内存的数据类型,都可以。7、集合中的内容输出,还是要从2到255逐一测试,检查是否在集合中,才能输出。用in函数。8、集合中有多少元素,可以用问题7中的方法。如果有更好的方法,俺也想知道。但就Object Pascal来说,只能逐位(比特位)检测。自己写函数也很简单。
      

  6.   

    最新的Delphi集合的范围扩大了,16位