标题:用删除法编写一个制作素数表的vfp程序
取消只看楼主
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 16楼 laowan001
这是程序的最后一段计算数据,整个程序是从1开始的,那只运算了2个外循环,一次外循环可以处理510510自然数段内的92160个数值。运算结果不对。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 15:00
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 15楼 laowan001
那个数是需要处理的用数,里边有多少个素数找出来就可以了。不过,本问题不要用此程序,基本效仿把数排成一行或一列,然从素数3开始,划去其倍数,(奇数等差数列,不含1),继续划去5得倍数,一直这样划下去,直到最后一个素数倍划完为止,当然这个最后素数是本组数中最大的那个开方值前的最大素数。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 15:12
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 18楼 laowan001
所用到到的两个表已经压缩后,发在本主题中了,在三楼或四楼,原理简单,与单个筛选素数一致,只是本问题需要成批处理数据,就这点区别。我并没有编出程序,也没有结果,只是大概知道过程,一共涉及4个表,有一个表放素数(即运算结果),一个表放数据源(或者被处理数据,它是一个自然数段,经过了预处理,后续调用时,只需加周期9699690即可),数据a和数据b两个表是最内层用到的表,它们互相替换,直到完成最后一步筛查,把最终结果抄写到素数表结果中即可。奥,忘了,还有预先制的素数表,在最里层需要它做筛选条件,这样一共5表。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 15:33
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 20楼 laowan001
不是不需要用程序,而是不用我发到这个主题中的程序获得素数表。要用主题中的,从新设计一个程序来完成任务。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 15:38
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 21楼 吹水佬
关键是要用素数表,必须提前制作。就是用主题中的方法来制作素数表(我发了另一种制作素数表的程序,太慢了,无法满足要求)。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 15:42
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 26楼 吹水佬
是这种方式与处理结果。只不过这种没有分段,如果一次性处理一亿个数据,数组的长度有没有限制,即是没有限制,加大到10亿的数据量如何?最关键的是可能还大。所以必须改变一下,每次只处理一个固定周期内的数据,我给的数据源是9699690为周期的,里边有1658880个数据等待处理(一次性处理,不是一个一个的处理),每循环一个外循环值,数据源中的值加一个周期数9699690,进入第二个外循环,最里层的循环用mod(n,p)是否为0作为筛选条件(与其加它本身是一会事儿),在这个过程中,如果有被整除的就去掉了,不在进入下一个素数的排查之内。把最后一个待检验素数执行以后,判断最内层循环次数的奇偶性,找出那个是最终结果(数据a与数据b选其一,当然是正确的那个),把结果抄写到盛方素数的表中,此次外循环一次的数据处理完毕,进入第二轮即可。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 17:12
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
现在编写出来个雏形,正在运行,看一看,运行结果如何,再发到网上,让大家提出宝贵意见,或者更好的优化方案。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 20:00
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
CLEAR
SELECT 1
USE D:\标记法\数据源表.DBF ALIAS 数据源
SELECT 2
USE D:\标记法\素数表5万.DBF ALIAS 素数表参
SELECT 3
USE D:\标记法\数据表a.DBF ALIAS 数据a
SELECT 4
USE D:\标记法\数据表b.DBF ALIAS 数据b
SELECT 5
USE D:\标记法\素数表结果.DBF ALIAS 素数表果
                                  && bcz=510510  
kssj=SECONDS()                     
FOR i=1 TO 2
@12,10 SAY i
   SELECT 3
   DELETE ALL &&因为此表将写入新的数据,所以提前清空数据,即记录条值
   PACK
   SELECT 1
   GO 1
   FOR j=1 TO 1658880
   sss=素数式
   dclz=sss+(i-1)*9699690  &&dclz是待处理值
   SELECT 3
   APPEND BLANK
   REPLACE 数据1 WITH dclz
   SELECT 1
   SKIP
   ENDFOR
      SELECT 3
      GO 1658880
      bpz=数据1
      Kf=INT(SQRT(bpz))
      GO 1
      SELECT 2
      GO 1
      COUNT ALL FOR 素参<=kf TO jlh  && jlh=RECNO()
      xhcs=jlh-8 &&xhcs是循环次数的简写(第一个字母代替)
      SELECT 2   
      GO 9
      FOR k=1 TO xhcs
       sc=素参
        IF  MOD(k,2)=1
          SELECT 4
          DELETE ALL
          PACK
          SELECT 3
          jlts1=RECCOUNT()  &&把数据a表中的记录条总数赋给变量:jlts1
          GO 1
            for h1=1  to jlts1
            sj1=数据1
            ys1=MOD(sj1,sc)
            IF ys1=0
            ELSE
            SELECT 4
            APPEND BLANK
            REPLACE 数据2 WITH sj1
            ENDIF
            SELECT 3
            SKIP
            ENDFOR
         ELSE
           SELECT 3
           DELETE ALL
           PACK
           SELECT 4
           jlts2=RECCOUNT()  &&把数据b表中的记录条总数赋给变量:jlts2
            GO 1
            for h2=1  to jlts2
            sj2=数据2
            ys2=MOD(sj2,sc)
            IF ys2=0
            ELSE
            SELECT 3
            APPEND BLANK
            REPLACE 数据1 WITH sj2
            ENDIF
            SELECT 4
            SKIP
            ENDFOR
          ENDIF
       SELECT 2
       skip  
       ENDFOR
          IF MOD(xhcs,2)=1
          SELECT 4
          jlts3=RECCOUNT()
          GO 1
          for h3=1  to jlts3
           sj3=数据2
           SELECT 5
           APPEND BLANK
           REPLACE 素数 WITH sj3
           SELECT 4
           SKIP
          ENDFOR
          ELSE
          SELECT 3
          jlts4=RECCOUNT()
          GO 1
          for h4=1  to jlts4
           sj4=数据1
           SELECT 5
           APPEND BLANK
           REPLACE 素数 WITH sj4
           SELECT 3
           SKIP
          ENDFOR
          ENDIF
 ENDFOR
 =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是我编写的程序,能正常运行,两周的运算时间为:29分40.24秒,在素数表结果中存储了1234399个数据,第一个1不是素数,第二个素数从3119开始的,3119前有443个素数,由1234399-1+443=1234841个素数,与以前方法制作的素数表中2*9699690=19399380内的素数个数一致,说明算法正确。
还是不满意运行时间,仍就偏大,不知道以前的方法运行时间是多少了(有空运行后再比对)。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 20:44
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
运行第三第四周,用时42分48.07秒

素数问题的解决是我学习编程永恒的动力。
2021-09-14 21:35
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
CLEAR
SELECT 1
USE D:\vfp温习\素数式至19表.DBF ALIAS 素数式表
SELECT 2
USE D:\vfp温习\素数表万3.DBF ALIAS 素数表万3
SELECT 3
USE D:\vfp温习\素数表实验.DBF ALIAS 素数表 &&当时仅改变了别名,没有改原名,在素数表亿新后增加了198-200周期素数,改正,并去掉了后续素数
*INPUT "请输入预先值 K= " TO yxk
*INPUT "请输入步长值 bcz= " TO bcz
*INPUT "请输入初始值 csz= " TO csz
*INPUT "请输入外循环起始值 xks= " TO xks
*INPUT "请输入外循环终结值 zds= " TO zds
bcz=9699690 &&从2乘到17,即素数17的素数阶乘
kssj=SECONDS()                      &&取出开始时间
FOR i=1 TO 2
@12,10 SAY i
            &&调了下顺序,原来在FOR j=1 TO 92160 的下边,执行第一个外循环,提示已经到了表尾
FOR j=1 TO 1658880
@22,20 SAY j
SELECT 1
GO j
sss=素数式
bpz=sss+(i-1)*bcz               &&计算被判断值
Kf=INT(SQRT(bpz))                   &&求出被判断值的开方根
SELECT 2
GO 1
COUNT ALL FOR 素数<=kf TO jlh  &&借用原来的记录号,实际上统计kf以前的素数个数
  && jlh=RECNO()
SELECT 2   
GO 9                                &&从第二条记录开始读取素数(3)
FOR k=1 TO jlh-8                     &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
qmz=MOD(bpz,素数)                   &&以读取的素数为条件,对被判断值求模
IF qmz=0 && OR qmz=2 OR qmz=6 OR qmz=8  如果符合这四个约定条件之一,就进行相应工作.如果一个也没有符合条件的,直接使记录指针向下移动一个(SKIP)
EXIT                                &&因为符合条件,则做完相应工作后跳出内循环
ENDIF
SKIP                                &&素数表指针向下移动一个
ENDFOR
IF k>jlh-8
SELECT 3               &&打开保存求解结果的信息表
APPEND BLANK                        &&增加一条空记录
REPLACE 素数 WITH bpz && 把bpz赋给素数        
ENDIF
ENDFOR
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
一个一个的处理方法用时:65分41.26秒,明显比一个批次一个批次处理要慢的多。

素数问题的解决是我学习编程永恒的动力。
2021-09-14 22:08



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-506838-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.660371 second(s), 8 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved