数学中国

 找回密码
 注册
搜索
热搜: 活动 交友 discuz
楼主: 白新岭

[原创]请教vfbpgyfk先生一个编程问题

  [复制链接]
 楼主| 发表于 2020-12-7 19:53 | 显示全部楼层
SELECT 1
USE D:\vfp新素数式\素数31不余4.dbf ALIAS 素数31  &&比制作表的素数值小(即下表)
SELECT 2
USE D:\vfp新素数式\素数37余4参考.dbf ALIAS 素数37余数 &&比上边已筛除的素数值要大
SELECT 3
USE D:\vfp新素数式\素数37不余4.dbf ALIAS 素数37  &&即将筛除素数余数的盛放表,与上表(参考表)素数值相同
kssj=SECONDS()   &&取出开始时间
SELECT 1   
GO 1            
   FOR i=1 TO 2000 &&这个范围远远超过出现最后一个余数的记录条数
    A=素31 &&改成表1的字段名
    jlz=RECNO()  &&记住指针所在位置
    SELECT 2
    jlzs2=RECCOUNT()  &&核对表2记录条总数
    IF jlzs2=37 &&改成将要制作参考表的素数值,即表2中的素数值
    exit
    ENDIF
    ys=MOD(A,37) &&改成将要制作参考表的素数值,即表2中的素数值
    SELECT 2
           count all for ys=余数37 to js  &&改成将要制作参考表的字段名,即表2中的字段名
           IF js=0
          SELECT 2
          APPEND BLANK
          REPLACE 余数37 WITH ys &&改成本次追加记录的字段名,即表2的字段名
          REPLACE 记录值 WITH jlz
          ENDIF
          SELECT 1
          skip
   ENDFOR
   SELECT 2
   GO 37
   DELETE NEXT 1
   pack
SELECT 1
GO 1
   &&jlzs1=RECCOUNT()  核对表2记录条总数            
  DO WHILE NOT EOF() && FOR i=1 TO jlzs1  &&循环次数改成,SELECT 1 的总记录条数
    A=素31  &&设成表1的字段名
    ys=MOD(A,37) &&对3表的素数求余数
    SELECT 2
           count all for ys=余数37 to js
           IF js=1
          SELECT 3
          APPEND BLANK
          REPLACE 素37 WITH A &&改成本次追加记录的字段
          ENDIF
          SELECT 1
          skip
   ENDdo
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是一步到位程序,它可以解决从小点的素数通过的素数式直接升级到通过下一个素数关口的素数式,
接下来,我会用循环代替,加上素数,一次性经过多个素数的关卡,我命名为, 双螺旋程序(或真假替身程序),程序的命名形象的描绘出算法和流程图,即在第一次外循环时,如果表一是A表,则第二次外循环时,编程B表;同理在第一次外循环时,如果表二是B表,则第二次外循环时,变成A表,每次外循环都涉及A表和B表,但是递增一个外循环,A表就成了B表,B表就成了A表,它们相互替代,相互变身,你既是我,我即是你,不分彼此,又分彼此;不知A是真身,还是B是真身。这就是双螺旋程序(或真假美猴王程序)。
它主要是以解决最密素数式问题而设,不过可以用于筛选素数上,或许这种思路比用直接求素数要快的多,到一亿,只需过1万以前的素数即可,从头开始往后标记被素数整除的数,然后物理删除(符合条件做标记),制作下一个表时,物理删除已经做过标记的记录。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-8 15:12 | 显示全部楼层
SELECT 1
USE D:\vfp新素数式\素数a不余4.dbf ALIAS 素数a  &&比制作表的素数值小(即下表)        原表在条件为真时
SELECT 2
USE D:\vfp新素数式\素数a余4参考.dbf ALIAS 素数a余数 &&比上边已筛除的素数值要大  在条件为假时参考表
SELECT 3
USE D:\vfp新素数式\素数b不余4.dbf ALIAS 素数b  &&即将筛除素数余数的盛放表,与上表(参考表)素数值相同   在条件为真时制造表,即新表
SELECT 4
USE D:\vfp新素数式\素数b余4参考.dbf ALIAS 素数b余数 &&比上边已筛除的素数值要大         在条件为真时参考表
SELECT 5
USE D:\vfp新素数式\素数表.dbf ALIAS 素数表参 &&即将筛除素数余数的盛放表,与上表(参考表)素数值相同
kssj=SECONDS()   &&取出开始时间
SELECT 5
GO 13 &&从素数37开始
FOR n=1 TO 4
ss=素数
IF MOD(n,2)=1 &&条件为真时,由a表制作b表,a表用一个,b表用2个,a表,为1和2,1表为主;b表为3和4,3表为主表
SELECT 1   
GO 1            
   FOR i=1 TO 10000 &&这个范围远远超过出现最后一个余数的记录条数
    A=素a &&改成表1的字段名
    jlz=RECNO()  &&记住指针所在位置
    SELECT 4
    jlzs2=RECCOUNT()  &&核对表2记录条总数
    IF jlzs2=ss &&改成将要制作参考表的素数值,即表2中的素数值
    exit
    ENDIF
    ys=MOD(A,ss) &&改成将要制作参考表的素数值,即表2中的素数值
    SELECT 4
           count all for ys=余数b to js  &&改成将要制作参考表的字段名,即表2中的字段名
           IF js=0
          SELECT 4
          APPEND BLANK
          REPLACE 余数b WITH ys &&改成本次追加记录的字段名,即表2的字段名
          REPLACE 记录值 WITH jlz
          ENDIF
          SELECT 1
          skip
   ENDFOR
   SELECT 4
   GO ss
   DELETE NEXT 1
   pack
SELECT 1
GO 1
   &&jlzs1=RECCOUNT()  核对表2记录条总数            
  DO WHILE NOT EOF() && FOR i=1 TO jlzs1  &&循环次数改成,SELECT 1 的总记录条数
    A=素a  &&设成表1的字段名
    ys=MOD(A,ss) &&对3表的素数求余数
    SELECT 4
           count all for ys=余数b to js
           IF js=1
          SELECT 3
          APPEND BLANK
          REPLACE 素b WITH A &&改成本次追加记录的字段
          ENDIF
          SELECT 1
          skip
   ENDDO
   
ELSE  &&条件为假时,由b表制作a表,b表用一个,a表用2个  (a表,为1和2,1表为主;b表为3和4,3表为主表)

SELECT 3  
GO 1            
   FOR i=1 TO 10000 &&这个范围远远超过出现最后一个余数的记录条数
    A=素b &&改成表1的字段名
    jlz=RECNO()  &&记住指针所在位置
    SELECT 2
    jlzs2=RECCOUNT()  &&核对表2记录条总数
    IF jlzs2=ss &&改成将要制作参考表的素数值,即表2中的素数值
    exit
    ENDIF
    ys=MOD(A,ss) &&改成将要制作参考表的素数值,即表2中的素数值
    SELECT 2
           count all for ys=余数a to js  &&改成将要制作参考表的字段名,即表2中的字段名
           IF js=0
          SELECT 2
          APPEND BLANK
          REPLACE 余数a WITH ys &&改成本次追加记录的字段名,即表2的字段名
          REPLACE 记录值 WITH jlz
          ENDIF
          SELECT 3
          skip
   ENDFOR
   SELECT 2
   GO ss
   DELETE NEXT 1
   pack
SELECT 3
GO 1
   &&jlzs1=RECCOUNT()  核对表2记录条总数            
  DO WHILE NOT EOF() && FOR i=1 TO jlzs1  &&循环次数改成,SELECT 1 的总记录条数
    A=素b  &&设成表1的字段名
    ys=MOD(A,ss) &&对3表的素数求余数
    SELECT 2
           count all for ys=余数a to js
           IF js=1
          SELECT 1
          APPEND BLANK
          REPLACE 素a WITH A &&改成本次追加记录的字段
          ENDIF
          SELECT 3
          skip
   ENDDO
   ENDIF
   SELECT 5 && 外循环是选择素数表
   skip
   endfor
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是一个解决最密素数式问题的一个高级程序,同过a表,b表的相互替换,获得最终结果。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-9 21:16 | 显示全部楼层
SELECT 1
USE D:\素数式以跨度为准绳\素数式30乘14.dbf ALIAS 素数30
SELECT 2
USE D:\素数式以跨度为准绳\素数式420临时表.dbf ALIAS 素数式临表
sELECT 3
USE D:\素数式以跨度为准绳\素数式420标识.dbf ALIAS 素数式标
kssj=SECONDS()                      &&取出开始时间
   FOR  i=1000001 TO 5000000
   @ 5,12 say i
     SELECT 1
     GO 1
     DO WHILE NOT EOF()
     sss=素数30
     y=30*(i-1)+sss
        IF  mod(y,7)=0 OR mod(y,11)=0 OR mod(y,13)=0 or mod(y,17)=0 OR  mod(y,19)=0 && mod(y,3)=0 OR  mod(y,5)=0
          ELSE
          SELECT 2
          APPEND BLANK
          REPLACE 素数30临 WITH y &&改成本次追加记录的字段
        ENDIF
        SELECT 1
        skip
      ENDdo
      SELECT 2
        jlz=RECCOUNT()
      GO 1
      sskt=素数30临  &&素数式开头
      GO bottom
      ssjw=素数30临 &&素数式结尾
      IF ssjw-sskt=420 AND jlz=77
      sELECT 3
           APPEND BLANK
          REPLACE 序号 WITH i
          REPLACE 记录值 WITH jlz
        ENDIF
        SELECT 2
        DELETE all
        pack
   endfor
          =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是目前我最新的算法,有待进一步完善,以达到一步到位的结果。循序渐进,以螺旋式上升,这是学习vfp经验之言。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 13:01 | 显示全部楼层
SELECT 1
USE D:\回到本源\素数式至101.dbf ALIAS 素数式101
SELECT 2
USE D:\回到本源\最密生素数类型标本.dbf ALIAS 素数式标本
kssj=SECONDS()                      &&取出开始时间
SELECT 1
   GO 1
   FOR  i=1 TO 26573563   && 总记录条26573663
    x=素数101
    jlz=RECNO() && 返回指针所在记录值
   FOR j=1  TO 100
   y=素数101
   jlz1=RECNO()
   z=y-x
        IF z=30 AND j>=8
        SELECT 1
        GO jlz
        c=素数101
        SKIP
        s=0
        ss=0
        FOR k=1 TO j
        d=素数101
        e=d-c
        s=s+e
        ss=ss+s
        SELECT 1
        skip
        ENDFOR
        SELECT 2
        count all for ss=二阶累计 to js
          IF js=0
          SELECT 2
          APPEND BLANK
          REPLACE k值 WITH j+1 &&改成本次追加记录的字段
          REPLACE 二阶累计 WITH ss
          REPLACE 开头记录 WITH jlz
          REPLACE 开头素式 WITH x
          REPLACE 总跨度 WITH 30
          ENDIF
        ENDIF
        IF z>30
        EXIT
        ENDIF
       SELECT 1
       GO jlz1+1
    ENDFOR
SELECT 1
GO jlz+1
endfor
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是一个过了101前素数关卡的素数式中寻找最密k生素数式的不同类型程序。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-11 19:37 | 显示全部楼层
SELECT 1
USE D:\回到本源\素数式至19.dbf ALIAS 素数式19
SELECT 2
USE D:\回到本源\最密生素数类型标本.dbf ALIAS 素数式标本
kssj=SECONDS()                      &&取出开始时间
SELECT 1
   GO 1
   FOR  i=1 TO 1658780   && 总记录条26573663 循环次数是素数式表中记录条数---减k生素数式的k值,尽量比k大点
    x=素19  &&先定个橛子,固定住它
    jlz=RECNO() && 返回指针所在记录值,记下指针位置
   FOR j=1  TO 100  && 内循环,它的值比k值大些,因为跨度内可能是小于k的素数式个数,也可能比k值大,需要进一步筛查
   y=素19 &&从0位开始,
   jlz1=RECNO()  &&记录下位置,指针文职
   z=y-x  &&离开第一个素数式的距离(相对距离)
        IF z=420 AND j>=76 &&判断素数式个数是否大于等于k,因为开始位置,占一个素数式。跨度必须是420,
        SELECT 1  &&符合条件后,从新计算一阶累计和,二阶累计和,以为后边是否储存做准备,尽量拆除重复数据,以减小储存量
        GO jlz && 返回符合条件的位置,进行一轮循环,目的是计算s(sum),计算ss(二阶累计和)
        c=素19
        SKIP
        s=0  &&先给它赋值,以0开始
        ss=0  &&先给它赋值,以0开始
        FOR k=1 TO j && 循环次数为j,实际上,并非从0开始,而是以第二个的差值,开始,总的是循环k-1次
        d=素19
        e=d-c &&求出离开固定位置的差值,
        s=s+e &&一阶累计和值
        ss=ss+s  &&二阶累计和值
        SELECT 1 &&循环一次移动一下指针,下移一个,好改变e值,进而影响,s,ss
        skip
        ENDFOR  &&结束求和运算
        SELECT 2  &&选择要储存的表
        count all for ss=二阶累计 to js &&把表中已有的记录中,符合条件的记录条个数赋给变量js
          IF js=0 &&如果没有同样的记录
          SELECT 2 &&就选择储存表,把该记录的数据,记录下来
          APPEND BLANK
          REPLACE k值 WITH j+1 &&改成本次追加记录的字段
          REPLACE 二阶累计 WITH ss
          REPLACE 开头记录 WITH jlz
          REPLACE 开头素式 WITH x
          REPLACE 总跨度 WITH 420
          ENDIF
        ENDIF
        IF z>420 && 如果跨度已经超过定值,就跳出循环
        EXIT
        ENDIF
       SELECT 1
       GO jlz1+1 &&进行下一个素数式的判断
    ENDFOR
SELECT 1
GO jlz+1
endfor
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这楼的与上楼一样,只是加了注解,目的为自己以后编程做个参考。也利于读者们对程序的理解。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-12 11:37 | 显示全部楼层
SELECT 1
USE D:\回到本源\素数式至19.dbf ALIAS 素数式19 &&与素数2-19互素的数(或者式子)
SELECT 2
USE D:\回到本源\最密生素数类型标本.dbf ALIAS 素数式标本 &&已经初步筛选出来的数据,作为初步条件,待进一步验证
SELECT 3
USE D:\回到本源\余数参考表.dbf ALIAS 余数表 &&作为过程表,先一个素数一个素数的过关,然后看剩余的素数式个数是否为77个
SELECT 4
USE D:\回到本源\临时k生素数式表.dbf ALIAS 临时k素式表 &&临时存储k生素数式,为最终存储做准备
SELECT 5
USE D:\回到本源\最密生素数类型标本升级.dbf ALIAS 素数式标本升级  &&需要填写真正的k生素数式
SELECT 6
USE D:\回到本源\素数表.dbf ALIAS 素数表  &&需要填写真正的k生素数式
kssj=SECONDS()                      &&取出开始时间
SELECT 2
   GO 6232
   FOR  i=6232 TO 26231   && 总记录条26573663
    x=k值  && jlz=RECNO() && 返回指针所在记录值
    ktjl=开头记录
    ktss=开头素式
    IF x=77
    SELECT 1
    GO ktjl
    ktss=素19  && 把“素19”的值赋给素数式19
   FOR j=1  TO 77
   y=素19
   jlz2=RECNO()
   z=y-ktss
   SELECT 4
   APPEND BLANK
   REPLACE k式 WITH z &&把与定了橛子的素数式与指针所在位置的素数式,绝对值赋给“k式”,做为接下来的检查表
    SELECT 1
    GO jlz2+1
    ENDFOR
    SELECT 6
    GO 8
       FOR m=1  TO 13
       ss=素数
    SELECT 4
    DO WHILE NOT EOF()
    ks=k式
      ys=MOD(ks,ss)
         SELECT 3
        count all for ys=余数 to js
          IF js=0
          SELECT 3
          APPEND BLANK
          REPLACE 余数 WITH ys &&改成本次追加记录的字段
          ENDIF
          SELECT 4
          skip
        ENDDO
        SELECT 3
        zjlts=RECCOUNT()  &&总记录条数
        IF zjlts=ss
        EXIT
        ENDIF
       SELECT 6
       SKIP
       ENDFOR
       IF m=13
       SELECT 5
       APPEND BLANK
       REPLACE k值 WITH 77 &&改成本次追加记录的字段
          REPLACE 记录值 WITH ktjl
          REPLACE 开头素素式 WITH ktss
          REPLACE 跨度值 WITH 420
        ENDIF
        ELSE
        EXIT
        endif
          SELECT 2
          SKIP
   endfor
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是在至素数19的素数式中,已经筛选出来跨度为420(长度421)的自然数段中,剩余素数式个数正好是77的素数式,经排查后发现一个也没有(为真正的最密k生素数式),接下来是导出,素数式个数大于77的,素数式链条了,先导出来,在升级,复而往返,最后达到目的。可以混着导出,不论它是78的,79的,80的,81的,一股脑的导出即可,视同一般素数式,无需考虑其它,寻找方法类同。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-12 11:51 | 显示全部楼层
上楼的考虑不周,再进入下一个素数考核前,没有清空余数表;同样在新的素数式考核前,也没有清空旧的临时k生素数式表,所以运行结果不一定正确。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-13 12:49 | 显示全部楼层
SELECT 1
USE D:\回到本源\素数式至19.dbf ALIAS 素数式19
SELECT 2
USE D:\回到本源\最密生素数类型标本.dbf ALIAS 素数式标本
SELECT 3
USE D:\回到本源\素数式至23简表.dbf ALIAS 素数式23
kssj=SECONDS()                      &&取出开始时间
   FOR  j=1 TO 23
   @ 5,9 say j
   SELECT 2
   FOR  k=1 TO  26082
    SELECT 2
     kz=k值
     ktjl=开头记录
     IF kz>77
     SELECT 1
     GO ktjl
     FOR i=1  TO  kz-1
      s19=素19
      y=s19+(j-1)*9699690
       @ 15,19 say y
        IF mod(y,23)=0
          ELSE
          SELECT 3
          APPEND BLANK
          REPLACE 素23 WITH y &&改成本次追加记录的字段
         ENDIF
         SELECT 1
         SKIp
        ENDFOR
        ENDIF
        SELECT 2
        SKIP
        jlh=RECCOUNT()
         @ 12,20 say jlh
      ENDFOR
      SELECT 2
      GO 1
     endfor
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是简约版的素数式23(所谓简约是挑着捡着之意,只针对性的选择部分素数式段落,而不是全部,要是全部也容不下)。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-14 21:10 | 显示全部楼层
只有深刻认识了素数式,才会用程序对它进行描述(进而进入计算)。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-15 11:42 | 显示全部楼层
SELECT 1
USE D:\回到本源\素数式至23简表再化简.dbf ALIAS 素数式23
SELECT 2
USE D:\回到本源\最密生素数类型标本.dbf ALIAS 素数式标本
kssj=SECONDS()                      &&取出开始时间
SELECT 1
   GO 1
   FOR  i=1 TO 4046008   && 总记录条26573663 循环次数是素数式表中记录条数---减k生素数式的k值,尽量比k大点
    x=素23  &&先定个橛子,固定住它
    jlz=RECNO() && 返回指针所在记录值,记下指针位置
   FOR j=1  TO 100  && 内循环,它的值比k值大些,因为跨度内可能是小于k的素数式个数,也可能比k值大,需要进一步筛查
   y=素23 &&从0位开始,
   jlz1=RECNO()  &&记录下位置,指针文职
   z=y-x  &&离开第一个素数式的距离(相对距离)
        IF z=420 AND j>=77 &&判断素数式个数是否大于等于k,因为开始位置,占一个素数式。跨度必须是420,
        SELECT 1  &&符合条件后,从新计算一阶累计和,二阶累计和,以为后边是否储存做准备,尽量拆除重复数据,以减小储存量
        GO jlz && 返回符合条件的位置,进行一轮循环,目的是计算s(sum),计算ss(二阶累计和)
        c=素23
        SKIP
        s=0  &&先给它赋值,以0开始
        ss=0  &&先给它赋值,以0开始
        FOR k=1 TO j && 循环次数为j,实际上,并非从0开始,而是以第二个的差值,开始,总的是循环k-1次
        d=素23
        e=d-c &&求出离开固定位置的差值,
        s=s+e &&一阶累计和值
        ss=ss+s  &&二阶累计和值
        SELECT 1 &&循环一次移动一下指针,下移一个,好改变e值,进而影响,s,ss
        skip
        ENDFOR  &&结束求和运算
        SELECT 2  &&选择要储存的表
        count all for ss=二阶累计 to js &&把表中已有的记录中,符合条件的记录条个数赋给变量js
          IF js=0 &&如果没有同样的记录
          SELECT 2 &&就选择储存表,把该记录的数据,记录下来
          APPEND BLANK
          REPLACE k值 WITH j &&改成本次追加记录的字段,这里不该加1,实际上j值就是k生素数式的k值
          REPLACE 二阶累计 WITH ss
          REPLACE 开头记录 WITH jlz
          REPLACE 开头素式 WITH x
          REPLACE 总跨度 WITH 420
          ENDIF
        ENDIF
        IF z>420 && 如果跨度已经超过定值,就跳出循环
        EXIT
        ENDIF
       SELECT 1
       GO jlz1+1 &&进行下一个素数式的判断
    ENDFOR
SELECT 1
GO jlz+1
endfor
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
一次性检测一定跨度最密素数式程序。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|数学中国 ( 京ICP备05040119号 )

GMT+8, 2025-5-15 03:12 , Processed in 0.099586 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表