数学中国

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

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

  [复制链接]
 楼主| 发表于 2019-3-3 12:50 | 显示全部楼层
本帖最后由 白新岭 于 2019-3-4 04:31 编辑

运行外循环7到9用时88分58.48秒,看来用时越来越长。第10至15个周期用时193分5.47秒;执行外循环N=16到18用时108分52.38秒

今天判断一个数是否为3生素数的生成元,范围9699690,里边有323323*2个值,用时9分5.82秒。
 楼主| 发表于 2019-3-4 12:28 | 显示全部楼层
在Excel软件中,逻辑函数参数可以达到255个(版本我不知道),可在vfp软件中逻辑函数最多才6个(6个的可以通过,15个的不能识别),不知道是否可以用括号,里边用逗号隔开是否可以。
 楼主| 发表于 2019-3-4 12:40 | 显示全部楼层
CLEAR ALL
SELECT 1
USE c:\visualfoxpro项目\素数表万.DBF ALIAS 万素
SELECT 2
USE c:\visualfoxpro项目\三生素数生成元19.DBF ALIAS 三生成元19
    kssj=SECONDS()                      &&取出开始时间
   For N=1 to 323323
    @ 3,6 say N
        FOR M=17 TO 23 STEP 6
        @ 5,8 say M
         X=M+(N-1)*30
           SELECT 万素
           go 3
            FOR I=1 TO 5 &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。
            @ 2,5 say  素数万   
                IF  X%素数万=0 OR X%素数万=4 OR X%素数万=6
                  EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF I>5
                SELECT   三生成元19         &&打开盛放素数的表
                APPEND BLANK                &&增加一条空记录
                REPLACE 三生元19 WITH X     &&将N值付给素数
            ENDIF
        ENDFOR
   ENDFOR
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是用vfp程序产生的3生素数生成元(加9699690的整周期或者本身能产生3生素数的奇数,三生素数的排列结构为(0,2,4)数字是相邻素数的间隔,数字0表示本位,即第一个素数。
 楼主| 发表于 2019-3-4 18:53 | 显示全部楼层
CLEAR ALL
SELECT 1
USE c:\visualfoxpro项目\素数表万.DBF ALIAS 万素
SELECT 2
USE c:\visualfoxpro项目\三生素数生成元19.DBF ALIAS 三生成元19
SELECT 3
USE c:\visualfoxpro项目\三生素数合成结果.DBF ALIAS 三生合成结果
    kssj=SECONDS()                      &&取出开始时间
   For N=2 to 323322
    @ 3,6 say N
         FOR M=4 TO 16 step 6
          @ 4,8 say M
          X=M+N*30
          Y=X/2
          T=INT(X/9699690)+1
            FOR I=1 TO T
            SELECT 三生成元19
            go 1
            @ 5,10 say  三生元19
            SS1=三生元19+(N-1)*9699690
               DO WHILE SS1<Y+1
                Kf1=INT(SQRT(SS1))       &&求出奇数的开方根
                SELECT  万素             &&打开素数表
                LOCATE FOR 素数万>=kf1      &&根据开方根,查找最大素数
                DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数万>kf1    &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
                ENDCASE
                SSS1=RECNO()    &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
                  GO 8           &&从第一条记录开始读取素数(3)
                  FOR j1=1 TO SSS1-7      &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                   qmz1=MOD(SS1,素数万)   &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态。
                   qmz2=MOD(SS1,素数万)
                   qmz3=MOD(SS1,素数万)
                       IF qmz1=0 OR qmz2=4 OR qmz3=6
                         EXIT         
                        ENDIF
                       SKIP            &&素数表指针向下移动一个
                  ENDFOR
                  IF j1>sss1-7
                  SS2=X-SS1
                  Kf2=INT(SQRT(SS2))       &&求出奇数的开方根
                  SELECT  万素             &&打开素数表
                  LOCATE FOR 素数万>=kf2     &&根据开方根,查找最大素数
                  DO CASE
                  CASE EOF()          &&如果超出素数表最后一条记录
                       GO BOTTOM
                  CASE 素数万>kf2     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
                  ENDCASE
                  SSS2=RECNO()    &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
                  GO 8           &&从第一条记录开始读取素数(3)
                   FOR j2=1 TO SSS2-7      &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                   qmz4=MOD(SS2,素数万)   &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态。
                   qmz5=MOD(SS2,素数万)
                   qmz6=MOD(SS2,素数万)
                   IF qmz4=0 OR qmz5=4 OR qmz6=6
                     EXIT         
                   ENDIF
                   SKIP            &&素数表指针向下移动一个
                   ENDFOR
                   ENDIF
                   IF j2>SSS2-7
                 EXIT
                 ELSE
                SELECT 三生合成结果&&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 模30的偶数 WITH X           &&将N值付给素数
                ENDIF
              SKIP
              ENDDO
          ENDFOR
       ENDFOR
     ENDFOR
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
这个程序没有完成任务,从显示情况看,没有调取完三生素数生成元中符合条件的值,只是用了第一个数47,不知是go 1的杰作,还是do while的杰作,还是最后的条件语句的杰作,不得而知。
 楼主| 发表于 2019-3-5 05:48 | 显示全部楼层
本帖最后由 白新岭 于 2019-3-5 02:05 编辑

CLEAR ALL
SELECT 1
USE e:\用vfp求k生素数数量\素数表2.DBF ALIAS 素数表
SELECT 2
USE e:\用vfp求k生素数数量\三生素数生成元19.DBF ALIAS 三生成元19
SELECT 3
USE e:\用vfp求k生素数数量\三生素数表.DBF ALIAS 三生素数
    kssj=SECONDS()                      &&取出开始时间
   For N=0 to 10
    @ 12,15 say  N      
        SELECT 三生成元19
        go 1
        DO WHILE NOT EOF()
        @ 14,18 say 三生元19
            bpz=三生元19+N*9699690
            Kf=INT(SQRT(bpz))       &&求出奇数的开方根
            SELECT  素数表             &&打开素数表
            LOCATE FOR 素数>=kf      &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS=RECNO()    &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 8          &&从第一条记录开始读取素数(3)
            FOR j=1 TO SSS-7    &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                qmz=MOD(bpz,素数)   &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态。
                IF qmz=0 or qmz=4 or qmz=6
                    EXiT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF j>sss-7
                SELECT  三生素数      &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 三素 WITH bpz            &&将N值付给素数
           ENDIF
         SELECT  三生成元19
        skip
       ENDdo
   endfor
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
这是制作3生素数的程序。
106694663  这是最大一个三生素数的代表值(本程序计算出来的,当然不是针对所有三生素数而言)
go top
47 107 113 197 233 317 353 467重复,因为我从素数23开始作为判断条件,它们都是23平方盾以内,没有过筛,实际上在制作三生素数生成元时已经过滤过了,因为我用素数2,3,5,7,11,13,17,19制作的三生素数生成元,所以它们已经为三生素数了,还有吧17与23的给丢掉了,还有最特殊的一个11,所有三生素数都是以3或7作为个数位置上的数出现的,唯独11是以1的身份出现,仅此一例。
运行时间1032分5.57秒
 楼主| 发表于 2019-3-5 09:44 | 显示全部楼层
2019年3月5日:
我今天从原来的旧笔记本中vfp的表中移进了表,明明是.dbf后缀,提示信息说是数据库文件,我只好把它放在数据库中,当点击时,提示
信息又说,它不是数据库文件,再没有信息,我又只好移去(不知道点击删除会发生什么),我又从新填到表文件中(原先填数据库问件时
带着原来的路径,现在好像没有了),添加同样的一个表竟如此周折。
 楼主| 发表于 2019-3-5 19:20 | 显示全部楼层
CLEAR ALL
SELECT 1
USE c:\visualfoxpro项目\三生素数表.DBF ALIAS 三素表
SELECT 2
USE c:\visualfoxpro项目\三生素数合成结果.DBF ALIAS 三生合成结果
    kssj=SECONDS()                      &&取出开始时间
   For N=2 to 1000
    @ 3,6 say N
         FOR M=4 TO 16 step 6
          @ 4,8 say M
          X=M+N*30
          Y=X/2
                zhz=Y      &&求出偶数的中值
                SELECT  三素表             &&打开三素数表
                LOCATE FOR 三素>=zhz      &&根据三素表,查找最大三素数
                DO CASE
                CASE EOF()          &&如果超出三素数表最后一条记录
                        GO BOTTOM
                CASE 三素>zhz   &&如果找到三的素数中值大,就将记录指针退回一个,保证使用的最大三素数在中值内,小于等于即
                        SKIP -1
                ENDCASE
                SSS=RECNO()    &&记录下最大三素数(中值内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
                  GO 1           &&从第一条记录开始读取三素数
                  FOR j=1 TO SSS      &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                     I=J
                     Z=X-三素 &&以读取的三素数为条件,对X-三素数值进行判断,看一看是否在三生素数表内
                       LOCATE FOR Z=三素
                        IF RECNO()<58724
                         EXIT         
                        ENDIF
                       GO I+1         &&素数表指针向下移动一个
                  ENDFOR
                   IF j>SSS
                   SELECT 三生合成结果             &&打开盛放素数的表
                   APPEND BLANK                    &&增加一条空记录
                   REPLACE 模30的偶数 WITH X       &&将N值付给素数
                   ENDIF
       ENDFOR
     ENDFOR
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
这是寻找不能有三生素数合成的偶数(从理论上有解,模30的只有3种偶数有解,其余的偶数都无解)
 楼主| 发表于 2019-3-5 21:55 | 显示全部楼层
统计符合条件的记录格式给一个变量:
count [all] for 逻辑型表达式 to 变量
 楼主| 发表于 2019-3-5 21:55 | 显示全部楼层
统计符合条件的记录格式给一个变量:
count [all] for 逻辑型表达式 to 变量
 楼主| 发表于 2019-3-5 22:02 | 显示全部楼层
VFP命令的范围子句有哪四种?分别代表什么含义?
ALL表示所有记录
NEXT(N)从当前记录起的N个记录
RECORD(N)第N个记录
REST从当前记录起到最后一条记录
我主要用第二条命令,next (n)从当前记录起的n个记录
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-2 07:23 , Processed in 0.080078 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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