注册 登录
编程论坛 VFP论坛

用删除法编写一个制作素数表的vfp程序

独木星空 发布于 2021-09-13 21:47, 12492 次点击
标记法主题思路,标记法是把符合条件的标记为假flase,而不符合条件的标记为真,在vfp中是这样实现这个过程的,先用
本轮参与运算的,求出最大开方值,然后查出所在记录条位置,由此记录条作为筛选循环总次数,第一次现由源数据,加周
期值9699690(即2*3*5*7*11*13*17*19=9699690,一次性调入1658880个数据(就这些需要判断是否为素数,其余的已经被排
除掉了)。有了循环次数,有了被筛选数据,进入主要循环体,先调入第一个素数,划掉其倍数,其余的存入数据b(从数据
源先调入数据a),然后调入第二个素数,排查数据b中符合条件的,剩余的存入数据a(当然每次存数据以前,要把数据表先
清空),循环往始,直到调入最后一个素数为止。然后把最后存的数据,抄写到素数结果表。
进入下一批数据调入,即把数据源加一个周期值9699690,先判断开方值,把小于等于开方值的记录条作为本次的素数调入个
数的依据(即本次的排查次数),进入同样的循环,获得结果,抄写到素数结果表。直到全部周期结束为止。
外循环为周期数,内循环为开方值记录条数减去素数19前的个数8,比方开放值以内有1000个素数,则内主体循环次数为:
1000-8=992次,当然随着循环周期的扩大,内循环次数增多。内循环单次,需要判断值逐步减少,例如第一次调入1658880个
值,大概有1658880/23=72125数被去掉,1658880-72125=1586755/29=54715数被筛掉,这样下去,越往后被判断数越少。所以
成倒排三角形数据量。把最后剩余的数据存放在素数结果表中即可。
外循环步长9699690,即一次性可以判断这样的自然数段。
最原始的筛法,一个一个的去判断,筛除,也就是都在重复同一项工作,效率低下;而这种算法是一次性调入一个批次的数据(这个批次是一个自然数段落,一个递增周期),是众数,不是一个一个的来,而是一同进入,然后第一次就排除了,最多的数据(因为小素数先参与排查,根据几率均等原则,它的倍数最多)。
157 回复
#102
吹水佬2021-09-21 20:08
回复 101楼 独木星空
VFP是32位应用,32位无符号整数最大值‭4294967295‬(0xFFFFFFFF)
再大就会溢出

[此贴子已经被作者于2021-9-21 20:11编辑过]

#103
独木星空2021-09-21 21:43
回复 102楼 吹水佬
明白了:2^32=4294967296
#104
独木星空2021-09-29 06:52
回复 82楼 laowan001
laowan001先生提供的方法是我需要的方法,他用了数据源及素数表,这样可以把同类问题一块解决。先生有空时能不能用数组的方法,方式代替内循环中的处理数据,那种算法发上来,我好学习学习(虽然,您已经说了运算速度也差不多)。
#105
独木星空2021-09-29 07:01
回复 102楼 吹水佬
吹水佬版主的算法用时最少,速度最快。计算范围是2*2^32.再大,就溢出了。(只好把制作100亿内的素数表暂时搁置,现在已有40亿内的素数表了,每10亿划分一个表,有四个素数表)。再次感谢吹水佬版主的付出,和辛勤劳作,给我提供了优质的制作素数程序。我以前制作10亿的素数表,哩哩啦啦用了20天的时间。所以,还得沉下心,努力向大家学习。
#106
wengjl2021-09-29 16:04
只有本站会员才能查看附件,请 登录
#107
独木星空2021-09-30 08:56
回复 106楼 wengjl
昨天下载,大概看了一下,还没有应用。祝您,国庆节快乐!
#108
独木星空2021-10-02 19:43
CREATE CURSOR tt(bol L,num I)
仅这个语句就解释了一堆:
create cursor 创建光标
alias_name(alias是别名之意) [codepage(代码页)=nCodepage]
      (fname1  type(类型) [(precision(精确度)[,scale])
 scale n.(相对的)大小,规模,范围;尺度;标度;等级表;级别表;比例;比例尺;音阶;鳞;
 标准;级别;标尺;刻度尺;(测试心智发展等的)量表;(鳞翅目昆虫的)翅瓣;(皮肤的)鳞屑;
 鳞片;铁鳞;(金属在高温下形成的)氧化层,氧化皮;梯子;楼梯;
 [null | not null ][check IExpvession (检查报告)[ERROR cMessageText]]   错误信息传送
null  零.(我原来认为是空值之意,即单元格为空白,没有填写内容的单元格)
 adj.无法律效力的;无效的;无价值的;无用的;无意义的;无特色的;无特点的;不存在的;一无所有的;
 数量为零的;零的;空的;极限为零的;(测量仪器)零读数的,读数为零的;
 [Autoinc [Nextvalue  Nextvalue[stepValue ]]]
汽车工业?  下一个值             阶梯值
[Default,eExpression] [unique [collate cCollate Sequence]]
违约       表达式      独特的
adj.唯一的;独一无二的;独特的;无与伦比的;无可匹敌的;独有的;特有的;唯一(结果)的;唯一(值)的;
 collate 核对
 vt.校对;核对;对照;(图书馆工作中)核对,检查(书籍页码及其顺序);检验(印张顺序);
 授予(教区牧师)有俸职位;
 序列 Sequence
 [nocptrans][,fname2....]) |From array arrayName
  在线翻译还是原字母              数组
这是在线翻译获得的意思,形而上学的用是用了,真不知所以然。
#109
独木星空2021-10-03 15:56
DIMENSION Fib[20]
Fib[1]=1
Fib[2]=1
FOR i=3 TO 20
    n=i
   Fib[n]=Fib[n-1]+Fib[n-2]
   ?Fib[n]
 ENDFOR
今天简单的学习了下,数组的运用。上边的小程序,输出了从3到20的斐波那契数列的值(Fibonacci)
#110
独木星空2021-10-04 10:13
CLEAR
SELECT 1
USE D:\标记法\数据源表.DBF ALIAS 数据源
SELECT 2
USE D:\标记法\素数表5万.DBF ALIAS 素数表参
SELECT 5
USE D:\标记法\素数表结果.DBF ALIAS 素数表果
kssj=SECONDS()                     
FOR i=5 TO 6
@12,10 SAY i
dimension  arr[1658880]
SELECT 1
GO 1
    FOR j=1 TO 1658880
    arr[j]=素数式+(i-1)*9699690
    SELECT 1
    SKIP
    ENDFOR
      bpz=i*9699690
      Kf=INT(SQRT(bpz))
      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=素参
            FOR h=1 TO 1658880
                IF arr[h]>0
                  if MOD(arr[h],sc)=0
                   arr[h]=0
                   endif
                 ENDIF
             ENDFOR
       SELECT 2
       skip
       ENDFOR
           FOR l=1 TO 1658880
           IF  arr[l]>0
           SELECT 5
           APPEND BLANK
           REPLACE 素数 WITH arr[l]
           ENDIF
           ENDFOR
 ENDFOR
 =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是用数组代替,数据表a和数据表b后的程序。运行时间:17分49.91秒。
比起最开始用3和4表时,50分16.70秒快了不少,比起laowan001的程序1026秒还是稍微慢点,如果按吹水佬版主的建议,把查询最大素数记录条的语句改成乘法运算,或许比开方运算快点,不过一个外循环只判断一次,估计提高不了多少。
在用到数据源及素数表的情况下,不知道是否还可以进一步优化?
当然在这个问题处理上,吹水佬版主的程序运行最快,包括后来给的dll文件,更是一流,美中不足之处,就是不能嫁接移植到别的程序中去,因为没有用到数据源及素数表(前提条件,单纯的制作素数用处有点窄)。
#111
独木星空2021-10-05 09:09
SELECT 1
USE D:\素数式系数\素数表万.dbf ALIAS 素数表
SELECT 2
USE D:\素数式系数\k6生素数系数表1.dbf ALIAS 系数表
kssj=SECONDS()  &&取出开始时间
FOR n=1 TO 999
m=30*INT((n-1)/3)+iif(MOD(n,3)=1,6,iif(MOD(n,3)=2,24,30))
    @ 5,12 say n
    s=1.0000000000000000
         IF MOD(m,5)=0
          s=s*2
          ELSE
          s=s*1
         ENDIF
         IF MOD(m,7)=0
          s=s*2
          ELSE
          s=s*1
         ENDIF        
    SELECT 1
    GO 5
    pdz=.F.
     DO WHILE NOT pdz
           SELECT 1
           P=素数
           IF 2*P>m+6
           pdz=.T.
           endif
           DO case
           CASE  MOD(m,P)=0
           s=s*(P-3)/(P-6)
           CASE  MOD(m,P)=MOD(-2,P)
           s=s*(P-5)/(P-6)
           CASE  MOD(m,P)=MOD(2,P)
           s=s*(P-5)/(P-6)
           CASE  MOD(m,P)=MOD(-4,P)
           s=s*(P-5)/(P-6)
           CASE  MOD(m,P)=MOD(4,P)
           s=s*(P-5)/(P-6)
           CASE  MOD(m,P)=MOD(-6,P)
           s=s*(P-5)/(P-6)
           CASE  MOD(m,P)=MOD(6,P)
           s=s*(P-5)/(P-6)
           otherwise
           s=s*1
           ENDCASE
       SELECT 1
       SKIP
       enddo
         
           SELECT 2
           APPEND BLANK     &&增加一条空记录
           REPLACE k生 WITH 6 &&将B值付给素数式
           REPLACE 三kd WITH m &&将B值付给素数式
           REPLACE 系数 WITH 34.5972246684609*s &&将B值付给素数式
  ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
一个求两组最密3生素数中项差(或和)的(公式)系数程序。
#112
独木星空2021-10-06 16:11
CLOSE DATABASES
SELECT 1
USE d:\标记法\素数式至19.DBF ALIAS 素数式19
SELECT 2
USE d:\标记法\素数表参考.DBF ALIAS 素数表参
SELECT 3
USE d:\标记法\三生素数新.DBF ALIAS 三素表
DELETE ALL
PACK

SELECT 三素 数据1 FROM 三素表 WHERE 1=2 INTO CURSOR 数据a READWRITE

kssj = DATETIME()
FOR i=711 TO 720
@12,10 SAY i
    SELECT 式19+(i-1)*9699690 数据1,CAST(1 as INT) 数据mod FROM 素数式19 INTO CURSOR 数据a READWRITE

    SELECT 数据a
    GO BOTTOM     
    Kf=INT(SQRT(数据1))

    SELECT 2
   
    SCAN FOR RECNO()>8 AND 素数<=kf
        
        UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE 数据mod<>0 and 数据mod<>4 and 数据mod<>6

        SELECT 2
    ENDSCAN
   
    INSERT INTO 三素表 (三素) SELECT 数据1 FROM 数据a WHERE 数据mod<>0 and 数据mod<>4 and 数据mod<>6
   
 ENDFOR
 USE IN 数据a
 
 MESSAGEBOX( DATETIME()-kssj)
这是把laowan001先生的,稍微改了下,求最密三生素数程序
#113
laowan0012021-10-06 20:17
UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE 数据mod<>0 and 数据mod<>4 and 数据mod<>6
把上面这句改成下面这样试试时间的变化

UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE not inlist(数据mod,0,4,6)
#114
独木星空2021-10-06 21:46
回复 113楼 laowan001
CLOSE DATABASES
SELECT 1
USE d:\标记法\素数式至19.DBF ALIAS 素数式19
SELECT 2
USE d:\标记法\素数表参考.DBF ALIAS 素数表参
SELECT 3
USE d:\标记法\三生素数新.DBF ALIAS 三素表
DELETE ALL
PACK

SELECT 三素 数据1 FROM 三素表 WHERE 1=2 INTO CURSOR 数据a READWRITE

kssj = DATETIME()
FOR i=721 TO 722
@12,10 SAY i
    SELECT 式19+(i-1)*9699690 数据1,CAST(1 as INT) 数据mod FROM 素数式19 INTO CURSOR 数据a READWRITE

    SELECT 数据a
    GO BOTTOM     
    Kf=INT(SQRT(数据1))

    SELECT 2
   
    SCAN FOR RECNO()>8 AND 素数<=kf
        
        UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE not inlist(数据mod,0,4,6)

        SELECT 2
    ENDSCAN
   
    INSERT INTO 三素表 (三素) SELECT 数据1 FROM 数据a WHERE not inlist(数据mod,0,4,6)
   
 ENDFOR
 USE IN 数据a
 
 MESSAGEBOX( DATETIME()-kssj)
做了一个实验(测试),结果是,原来的程序用时495秒;改变后,用时446秒;相差49秒,是一个不小的进步。
#115
laowan0012021-10-06 21:58
SCAN FOR RECNO()>8 AND 素数<=kf
        
        UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE not inlist(数据mod,0,4,6)

        SELECT 2    && 这句可以去掉,也许能省掉一点时间
ENDSCAN
#116
独木星空2021-10-07 07:23
回复 115楼 laowan001
CLOSE DATABASES
SELECT 1
USE d:\标记法\素数式至19.DBF ALIAS 素数式19
SELECT 2
USE d:\标记法\素数表参考.DBF ALIAS 素数表参
SELECT 3
USE d:\标记法\三生素数新.DBF ALIAS 三素表
DELETE ALL
PACK

SELECT 三素 数据1 FROM 三素表 WHERE 1=2 INTO CURSOR 数据a READWRITE

kssj = DATETIME()
FOR i=721 TO 722
@12,10 SAY i
    SELECT 式19+(i-1)*9699690 数据1,CAST(1 as INT) 数据mod FROM 素数式19 INTO CURSOR 数据a READWRITE

    SELECT 数据a
    GO BOTTOM     
    Kf=INT(SQRT(数据1))

    SELECT 2
   
    SCAN FOR RECNO()>8 AND 素数<=kf
        
        UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE not inlist(数据mod,0,4,6)

        && SELECT 2
    ENDSCAN
   
    INSERT INTO 三素表 (三素) SELECT 数据1 FROM 数据a WHERE not inlist(数据mod,0,4,6)
   
 ENDFOR
 USE IN 数据a
 
 MESSAGEBOX( DATETIME()-kssj)
几乎不受影响,用时443秒。
#117
独木星空2021-10-07 07:47
回复 115楼 laowan001
CLOSE DATABASES
SELECT 1
USE d:\标记法\素数式至19.DBF ALIAS 素数式19
SELECT 2
USE d:\标记法\素数表参考.DBF ALIAS 素数表参
SELECT 3
USE d:\标记法\三生素数新.DBF ALIAS 三素表
DELETE ALL
PACK

SELECT 三素 数据1 FROM 三素表 WHERE 1=2 INTO CURSOR 数据a READWRITE

kssj = DATETIME()
FOR i=721 TO 722
@12,10 SAY i
    SELECT 式19+(i-1)*9699690 数据1,CAST(1 as INT) 数据mod FROM 素数式19 INTO CURSOR 数据a READWRITE

    SELECT 数据a
    GO BOTTOM     
    sj1=数据1

    SELECT 2
   
    SCAN FOR RECNO()>8 AND 素数*素数<=sj1
        
        UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE not inlist(数据mod,0,4,6)

        && SELECT 2
    ENDSCAN
   
    INSERT INTO 三素表 (三素) SELECT 数据1 FROM 数据a WHERE not inlist(数据mod,0,4,6)
   
 ENDFOR
 USE IN 数据a
 
 MESSAGEBOX( DATETIME()-kssj)
我自己私自改动了一下,运算不但没有提速,还多用了几秒,想想也是,原来直接判断大小即可,现在每次还得算一次乘法,这不是得拨摆人吗?  用时451秒。
#118
独木星空2021-10-07 08:23
SELECT 1
USE D:\标记法\四生素数生成元.DBF  ALIAS 四生成元
SELECT 2
USE D:\标记法\素数表5万.DBF ALIAS 素数表
kssj=SECONDS()                      &&取出开始时间
    FOR i=1 TO 3187041
     @22,20 SAY i
     n=i
     bpz=19+(n-INT((n-1)/3)*3-1)*90+INT((n-1)/3)*210&&给被判断值置数,以循环值做变量。
        SELECT 素数表
        GO 5                                &&从第二条记录开始读取素数(3)
        FOR j=1 TO 5                     &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
        qmz=MOD(bpz,素参)                   &&以读取的素数为条件,对被判断值求模
        IF qmz=0 OR qmz=2 OR qmz=6 OR qmz=8 &&如果符合这四个约定条件之一,就进行相应工作.如果一个也没有符合条件的,直接使记录指针向下移动一个(SKIP)
        EXIT                                &&因为符合条件,则做完相应工作后跳出内循环
        ENDIF
        SKIP                                &&素数表指针向下移动一个
        ENDFOR
        IF j>5
        SELECT 1              &&打开保存求解结果的信息表
        APPEND BLANK                        &&增加一条空记录
        REPLACE 四生元 WITH bpz             &&将被判断值保存到被判断值字段中(被判断值数据栏)
        ENDIF
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是产生四生素数生成元程序,到了素数23,自然数跨度223092870.
制作了700245个种子。
#119
独木星空2021-10-07 09:49
回复 113楼 laowan001
CLOSE DATABASES
SELECT 1
USE d:\标记法\四生素数生成元.DBF ALIAS 生成元23
SELECT 2
USE d:\标记法\素数表参考.DBF ALIAS 素数表参
SELECT 3
USE d:\标记法\四生素数.DBF ALIAS 四素表

SELECT 四素 数据1 FROM 四素表 WHERE 1=2 INTO CURSOR 数据a READWRITE

kssj = DATETIME()
FOR i=1 TO 2
@12,10 SAY i
    SELECT 四生元+(i-1)*223092870 数据1,CAST(1 as INT) 数据mod FROM 生成元23 INTO CURSOR 数据a READWRITE

    SELECT 数据a
    GO BOTTOM     
    Kf=INT(SQRT(数据1))

    SELECT 2
   
    SCAN FOR RECNO()>9 AND 素数<=kf
        
        UPDATE 数据a SET 数据mod=MOD(数据1,素数表参.素数) WHERE not inlist(数据mod,0,2,6,8)

        SELECT 2
    ENDSCAN
   
    INSERT INTO 四素表 (四素) SELECT 数据1 FROM 数据a WHERE not inlist(数据mod,0,2,6,8)
   
 ENDFOR
 USE IN 数据a
 
 MESSAGEBOX( DATETIME()-kssj)
这是仿照laowan001先生的程序改造出来的,制作最密四生素数表程序,用时576秒。只是丢了最开始的12个四生素数,这点是预料之中的事。
运行第3,4周,用时837秒,比头1,2周增时,原因是它们循环次数增多,导致的。

[此贴子已经被作者于2021-10-7 10:14编辑过]

#120
独木星空2021-10-09 16:28
SELECT 1
USE D:\nm抽取m个数\模m余数统计.DBF ALIAS 模m余数统计
kssj=SECONDS()
y0=0
y1=0
y2=0
y3=0
y4=0
y5=0
y6=0
y7=0
y8=0
y9=0
y10=0
x=11*2+1 && m已经作为一个变量存在,所以文件大的没边,形成了1.9亿的记录条
    For i=1 to x
      FOR j=i+1  TO x+1
         FOR h=j+1  TO x+2
         FOR k=h+1  TO x+3
         FOR m=k+1  TO x+4
         FOR u=m+1  TO x+5
         FOR v=u+1  TO x+6
         FOR z1=v+1  TO x+7
         FOR z2=z1+1  TO x+8
         FOR z3=z2+1  TO x+9
         FOR z4=z3+1  TO x+10
             hz=i+j+h+k+m+u+v+z1+z2+z3+z4
             ys=MOD(hz,11)
               DO CASE
                  CASE ys=0
                  y0=y0+1
                  CASE ys=1
                  y1=y1+1
                  CASE ys=2
                  y2=y2+1
                  CASE ys=3
                  y3=y3+1
                  CASE ys=4
                  y4=y4+1
                  CASE ys=5
                  y5=y5+1
                  CASE ys=6
                  y6=y6+1
                  CASE ys=7
                  y7=y7+1
                  CASE ys=8
                  y8=y8+1
                  CASE ys=9
                  y9=y9+1
                  CASE ys=10
                  y10=y10+1
                  ENDCASE
          ENDFOR
          ENDFOR
          ENDFOR
         ENDFOR
         ENDFOR
          ENDFOR
          ENDFOR
         ENDFOR
      ENDFOR
      ENDFOR
   ENDFOR
   SELECT  1   &&打开盛放素数式的表
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 0 &&将B值付给素数式
          REPLACE 统计 WITH y0 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 1 &&将B值付给素数式
          REPLACE 统计 WITH y1 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 2 &&将B值付给素数式
          REPLACE 统计 WITH y2 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 3 &&将B值付给素数式
          REPLACE 统计 WITH y3 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 4 &&将B值付给素数式
          REPLACE 统计 WITH y4 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 5 &&将B值付给素数式
          REPLACE 统计 WITH y5 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 6 &&将B值付给素数式
          REPLACE 统计 WITH y6 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 7 &&将B值付给素数式
          REPLACE 统计 WITH y7 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 8 &&将B值付给素数式
          REPLACE 统计 WITH y8 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 9 &&将B值付给素数式
          REPLACE 统计 WITH y9 &&将B值付给素数式
          APPEND BLANK     &&增加一条空记录
          REPLACE m余 WITH 10 &&将B值付给素数式
          REPLACE 统计 WITH y10 &&将B值付给素数式
    =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是几抽几组和问题。主要是对for循环语句的运用。
#121
laowan0012021-10-09 16:43
回复 120楼 独木星空
几点小建议

程序代码:

* 建议一
y0=0
y1=0
y2=0
y3=0
y4=0
y5=0
y6=0
y7=0
y8=0
y9=0
y10=0
&& 改成下面语句
DIMENSION yy[11]    && yy数组取代变量y0~y10
FOR i=1 TO alen(yy)
    yy[i] = 0
ENDFOR

* 建议二
  ys=MOD(hz,11)
  DO CASE
  CASE ys=0
  y0=y0+1
  CASE ys=1
  y1=y1+1
  CASE ys=2
  y2=y2+1
  CASE ys=3
  y3=y3+1
  CASE ys=4
  y4=y4+1
  CASE ys=5
  y5=y5+1
  CASE ys=6
  y6=y6+1
  CASE ys=7
  y7=y7+1
  CASE ys=8
  y8=y8+1
  CASE ys=9
  y9=y9+1
  CASE ys=10
  y10=y10+1
  ENDCASE

&& 改成下面语句
ys=MOD(hz,11)
yy[ys+1] = yy[ys+1] + 1


* 建议三
  SELECT  1   &&打开盛放素数式的表
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 0 &&将B值付给素数式
  REPLACE 统计 WITH y0 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 1 &&将B值付给素数式
  REPLACE 统计 WITH y1 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 2 &&将B值付给素数式
  REPLACE 统计 WITH y2 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 3 &&将B值付给素数式
  REPLACE 统计 WITH y3 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 4 &&将B值付给素数式
  REPLACE 统计 WITH y4 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 5 &&将B值付给素数式
  REPLACE 统计 WITH y5 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 6 &&将B值付给素数式
  REPLACE 统计 WITH y6 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 7 &&将B值付给素数式
  REPLACE 统计 WITH y7 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 8 &&将B值付给素数式
  REPLACE 统计 WITH y8 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 9 &&将B值付给素数式
  REPLACE 统计 WITH y9 &&将B值付给素数式
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 10 &&将B值付给素数式
  REPLACE 统计 WITH y10 &&将B值付给素数式

&& 改成下面语句         
FOR i=1 TO alen(yy)
    INSERT INTO 模m余数统计 (m余,统计) VALUES (i-1,yy[i])
ENDFOR


[此贴子已经被作者于2021-10-9 16:46编辑过]

#122
独木星空2021-10-10 07:12
回复 121楼 laowan001
简练而精华。因为当时对数组方面的运用还不太了解,所以就用了那种语句。再就是do case语句很少运用,用的最多的就是for循环语句,其次do while语句。
    最后的增加记录值就用过APPEND BLANK 语句,基本上在程序中没有用过其他方法添加记录过。
    谢谢laowan001的改进。
#123
laowan0012021-10-10 10:53
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 10 &&将B值付给素数式
  REPLACE 统计 WITH y10 &&将B值付给素数式

同一条记录多个字段赋值可以写在同一行
  APPEND BLANK     &&增加一条空记录
  REPLACE m余 WITH 10,统计 WITH y10     &&将B值付给素数式,将B值付给素数式
#124
独木星空2021-10-11 08:52
回复 123楼 laowan001
谢谢!laowan001先生的建议。
#125
独木星空2021-10-13 08:35
回复 121楼 laowan001
SELECT 1
USE D:\问题x+2y的素数解\素数表.DBF ALIAS 素数表
SELECT 2
USE D:\问题x+2y的素数解\余数表.DBF ALIAS 余数表
kssj=SECONDS()
FOR k=1  TO 10
SELECT 1
GO k
ds=素数 &&ds对素之意
DIMENSION yy[ds]    && yy数组取代变量y0~y10
FOR i=1 TO alen(yy)
    yy[i] = 0
ENDFOR
SELECT 1
GO 1
FOR j=1 TO 32767
ss=素数
ys=MOD(ss,ds)
yy[ys+1] = yy[ys+1] + 1
SELECT 1
SKIP
endfor
    FOR h=1 TO alen(yy)
    INSERT INTO 余数表 (对素,余数,统计) VALUES (ds,h-1,yy[h])
    ENDFOR
endfor        
    =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
今天安照laowan001先生的建议制作了另外一个类似程序(打分素数)
#126
sam_jiang2021-10-13 09:57
求素数其实是个算法的问题,最简单的是穷举法,很简单就可以实现:
**下面的小程序可以迅速判断一个数是不是素数。
PARAMETERS lnNumber
LOCAL nYushu,i
IF lnnumber =1
    RETURN .t.
ENDIF
i=2
DO WHILE .t.
    IF i=lnnumber
        RETURN .t.               
    ELSE
        nyushu=MOD(lnNumber,i)
        IF nyushu=0
            RETURN .f.
        ELSE
            i=i+1
            LOOP
        ENDIF
    ENDIF   
ENDDO

当然,穷举法计算量比较大,还可以对程序进行优化,以提高运算速度。
1,直接筛除个位数是偶数的数,2除外。
2,直接筛除个位数是5的数,5除外。
3,各位数加起来和为3,6,9的(反复加),可以被3整除。
4,素数的个位数就只能是:1,3,7,9了,只要判定最后一位不是这4个数,肯定不是素数。
5,可以设置一个数组,用来保存从头遍历得到的素数(去掉2,3,5)。
6,遍历数组里的每个数,当除数,和穷举的数相除,没有的余数的肯定不是素数。
7,遍历整个数组下来,还有余数的,肯定是素数,再把它加入数组。

以上应该是目前最优算法,不服的可以出来交流。代码自己修改完成吧。。。
#127
独木星空2021-10-13 11:31
SELECT 1
USE D:\问题x+2y的素数解\素数表亿.DBF ALIAS 素数表亿
SELECT 2
USE D:\问题x+2y的素数解\余数表.DBF ALIAS 余数表
kssj=SECONDS()
FOR k=1  TO 10
SELECT 1
GO k
ds=素数 &&ds对素之意
DIMENSION yy[ds]    && yy数组取代变量y0~y10
FOR i=1 TO alen(yy)
    yy[i] = 0
ENDFOR
SELECT 1
GO 1
FOR j=1 TO 5761454
ss=素数
ys=MOD(ss,ds)
yy[ys+1] = yy[ys+1] + 1
SELECT 1
SKIP
endfor
    FOR h=1 TO alen(yy)
    INSERT INTO 余数表 (对素,余数,统计) VALUES (ds,h-1,yy[h])
    ENDFOR
endfor        
    =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
运行时间:0分59.54秒,不到1分钟,而那个32767的运行0.36秒。
#128
独木星空2021-10-13 11:40
回复 126楼 sam_jiang
你可以晒一晒你的代码,运行一下就知道优劣了。在本主题下,吹水佬的代码运行速度最快。还给出了,dll文件。只不过,没有按着设计要求去做,不能嫁接到其他应用程序中去。如果用了素数表,以及数据源表,就可以简单变形,计算其他相关联问题。
#129
sam_jiang2021-10-13 15:31
FoxPro是伪编译的,运行速度比其他语言慢的,用API估计是要快点的。
下面是纯FoxPro的,你看看需要多少时间,不同的机器配置,跑起来时间估计也相差大的。

PARAMETERS lnNumber
lnnumber=10000 &&调试用
LOCAL nYushu,i,nlen,nlast,ashuzu,m,k
timestart=SECONDS()
ndecimals=SET("Decimals" )
SET DECIMALS TO 0
K=5
nlen=0
i=1
DO WHILE lnnumber>i
    IF INLIST(i,1,2,3,5,7,9)
        nlen=nlen+1        
        DIMENSION ashuzu[nlen]
        ashuzu[nlen]=i
        i=i+1
        loop
    ENDIF

    IF INLIST(i,0,4,6,8)
        i=i+1
        loop
    ENDIF
    ***剔除能被2,5整除的数***
    nlast=VAL(RIGHT(ALLTRIM(str(i)),1))
    IF !INLIST(nlast,1,3,7,9)
        i=i+1
        loop
    ENDIF
    ***剔除能被3整除的数***
    m=geweihe(i)
    IF INLIST(m,3,6,9)
        i=i+1
        LOOP
    ELSE
    ***除此之外的数,去除以数组里的素数,如果余数为零则不是素数。***
        K=5
        DO WHILE k<=nlen
            nyushu=MOD(i,ashuzu[k])
            IF nyushu=0
                i=i+1
                exit
            ELSE
                k=k+1
                loop   
            ENDIF
        ENDDO                    
        nlen=nlen+1
        DIMENSION ashuzu[nlen]
        ashuzu[nlen]=i
        i=i+1
        loop            
    ENDIF     
   
ENDDO
timeend=SECONDS()
?timeend-timestart

FUNCTION geweihe
***这个函数返回各位数反复相加最后得到一个个位数***
PARAMETERS nshu
n=0
IF nshu>9
    FOR j=1 TO LEN(allt(STR(nshu)))
        n=n+VAL(SUBSTR(ALLTRIM((STR(nshu))),j,1))
    ENDFOR
    IF n>9
        n=geweihe(n)
    ENDIF
ENDIF
    RETURN n
ENDFUNC
#130
独木星空2021-10-13 22:09
回复 129楼 sam_jiang
PARAMETERS lnNumber  &&参数
lnnumber=100000 &&调试用
LOCAL nYushu,i,nlen,nlast,ashuzu,m,k  &&本地的,我理解为声明
timestart=SECONDS()  &&计时开始
ndecimals=SET("Decimals" ) &&集
SET DECIMALS TO 0  &&将小数设置为
K=5
nlen=0
i=1
DO WHILE lnnumber>i
    IF INLIST(i,1,2,3,5,7,9) &&如果输入
        nlen=nlen+1        
        DIMENSION ashuzu[nlen] &&尺寸
        ashuzu[nlen]=i
        i=i+1
        loop
    ENDIF

    IF INLIST(i,0,4,6,8) &&如果输入
        i=i+1
        loop
    ENDIF
    ***剔除能被2,5整除的数***
    nlast=VAL(RIGHT(ALLTRIM(str(i)),1))&&右侧所有直径,我理解为取字符串的右边第一个值
    IF !INLIST(nlast,1,3,7,9)&&非,如果输入,!是逻辑非
        i=i+1
        loop
    ENDIF
    ***剔除能被3整除的数***
    m=geweihe(i)
    IF INLIST(m,3,6,9) &&如果输入
        i=i+1
        LOOP
    ELSE
    ***除此之外的数,去除以数组里的素数,如果余数为零则不是素数。***
        K=5
        DO WHILE k<=nlen
            nyushu=MOD(i,ashuzu[k])
            IF nyushu=0
                i=i+1
                exit
            ELSE
                k=k+1
                loop   
            ENDIF
        ENDDO                    
        nlen=nlen+1
        DIMENSION ashuzu[nlen]
        ashuzu[nlen]=i
        i=i+1
        loop            
    ENDIF     
   
ENDDO
timeend=SECONDS()&&结束时间
?timeend-timestart

FUNCTION geweihe  &&函数
***这个函数返回各位数反复相加最后得到一个个位数***
PARAMETERS nshu  &&参数
n=0
IF nshu>9
    FOR j=1 TO LEN(allt(STR(nshu)))
        n=n+VAL(SUBSTR(ALLTRIM((STR(nshu))),j,1)) && SUBSTR 底座,我理解为取字符串中几个字符,包含如何取法
    ENDFOR
    IF n>9
        n=geweihe(n)
    ENDIF
ENDIF
    RETURN n
ENDFUNC
你的方法是安照你自己的流程图做的,或者说,按照你的算法编写的,在10000时,用时1.231;在100000时,87.994.你回头看一看别人的,特别是吹水佬版主的,那简直无法比,实际上算法最快的就是划出法,即把所有数排列成一排,从2开始划掉其倍数,接着下一3,再接着5,一直划下去就可以了,没有被划掉的就是素数。
你的方法只是测试了时间,没有成果,即无素数表产生,也有统计功能,报出有多少个素数,这有什么用处,只是用来链机器的,还是用来提高编写程序能力的,提的再高,没有应用,又有何用?
#131
独木星空2021-10-14 06:50
回复 129楼 sam_jiang
我的目的是通过,数据源,参照素数表,制作更大的素数表;而不是判断一个数是否为素数。
#132
sam_jiang2021-10-14 08:40
ashuzu里就是你要的所有素数,你可以将数组传回参数就可以了,我只是演示了如何将所有的素数筛选出来,并计算了一下所需时间。

呵呵,开拓一下思路,希望对你有帮助,没有的话就算了,就当茶余饭后的消遣。
#133
独木星空2021-10-14 10:46
回复 132楼 sam_jiang
我这个人是接受各种算法的,不论它的运算速度如何,统统吸纳。来强化自己编写程序的能力,只用自己的方法,永远接触不到更多的语句,命令,函数等信息。
    在这个问题上:吹水佬版主的运行速度最快,而且给提供dll文件,只不过没有用到我所提供的材料,也只能计算到32位(2^32)的2倍大,再大,就溢出了。
     而最符合题意的是:laowan001先生的,速度基本上也可以,最重要的是可以移植,嫁接到其他程序中,这是我最看重的地方。
     先生的思路,和流程图也别具一格。能不能适应更大应用就不知道了。
#134
laowan0012021-10-14 14:10
回复 131楼 独木星空

“我的目的是通过,数据源,参照素数表,制作更大的素数表;而不是判断一个数是否为素数”
如果把这句话分成两段来看,分号前后各一段
前一段是否可理解为:目的是制作更大的素数表?如果是这样,那可以继续看下面
如果是这样,那其实用什么方法并不重要,实现更大的素数表就行,当然方法不同效率会不同,这点可以做为取舍的依据
再看后一段,制作更大的素数表,其实结果必定是素数的集合,那判断一个数是否为素数则就是基本条件了

sam_jiang 所提出的方法可看做是一个基本方法

我是想建议:如果是为了“制作更大的素数表”,不妨多用些方法试试。

如果我的理解有误,请飘过
#135
独木星空2021-10-16 05:47
编写一个程序求Q(奇数)减2的n次方其值没有素数的奇数
猜想每一个奇数(大于等于5的)都可以表示成一个素数+2^n形式,编写一个vb6程序,寻找一亿内的反例。例如1048573这个数,它小于2^20=1048576,也就是1048573-2^n这个式子中的n可以从1取到19,在这19次取值中,其结果假设没有素数,则次数是一个反例,其中有一次是素数,就不是反例,程序设计中,也可以考虑,当为真时,跳出循环,执行下一个奇数。最好先制作素数表,或许也不快,不如直接判断,比起判断一个数是否为素数要容易的多(是指运算时间上)。大概就这么个意思,有不清楚的地方,在商榷。
这是发在vb6上的一个帖子,有兴趣的做一做。
#136
独木星空2021-10-16 05:48
SELECT 1
USE D:\方程p减2的n次方\素数表.DBF ALIAS 素数表
SELECT 2
USE D:\方程p减2的n次方\奇素数表.DBF ALIAS 奇素数表
kssj=SECONDS()                      &&取出开始时间
FOR i=99 TO 9999 STEP 2
@12,10 SAY i
zs=INT(LOG(i)/LOG(2))
FOR j=1 TO zs
@22,20 SAY j
bpz=i-2^j           &&计算被判断值
Kf=INT(SQRT(bpz))                   &&求出被判断值的开方根
SELECT 1                    &&打开素数表
LOCATE FOR 素数>=kf                 &&根据开方根,查找最大素数
DO CASE
CASE EOF()                          &&如果超出素数表最后一条记录
GO BOTTOM
CASE 素数>kf                        &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
SKIP -1
ENDCASE
jlh=RECNO()
SELECT 1 &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
GO 1                                &&从第二条记录开始读取素数(3)
FOR k=1 TO jlh                    &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
qmz=MOD(bpz,素数)                   &&以读取的素数为条件,对被判断值求模
IF qmz=0 && OR qmz=2 OR qmz=6 OR qmz=8  如果符合这四个约定条件之一,就进行相应工作.如果一个也没有符合条件的,直接使记录指针向下移动一个(SKIP)
EXIT                                &&因为符合条件,则做完相应工作后跳出内循环
ENDIF
SKIP                                &&素数表指针向下移动一个
ENDFOR
IF k>jlh
SELECT 2              &&打开保存求解结果的信息表
APPEND BLANK                        &&增加一条空记录
REPLACE 奇数 WITH i && 把bpz赋给素数   
REPLACE 参素 WITH bpz && 把bpz赋给素数
ENDIF
ENDFOR
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是制作能被表示的奇数程序。
#137
独木星空2021-10-16 05:49
SELECT 1
USE D:\方程p减2的n次方\素数表.DBF ALIAS 素数表
SELECT 2
USE D:\方程p减2的n次方\奇数表.DBF ALIAS 奇数表
kssj=SECONDS()                      &&取出开始时间
FOR i=9999 TO 99999 STEP 2
@12,10 SAY i
zs=INT(LOG(i)/LOG(2))
FOR j=1 TO zs
@22,20 SAY j
bpz=i-2^j           &&计算被判断值
Kf=INT(SQRT(bpz))                   &&求出被判断值的开方根
SELECT 1                    &&打开素数表
LOCATE FOR 素数>=kf                 &&根据开方根,查找最大素数
DO CASE
CASE EOF()                          &&如果超出素数表最后一条记录
GO BOTTOM
CASE 素数>kf                        &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
SKIP -1
ENDCASE
jlh=RECNO()
SELECT 1 &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
GO 1                                &&从第二条记录开始读取素数(3)
FOR k=1 TO jlh                    &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
qmz=MOD(bpz,素数)                   &&以读取的素数为条件,对被判断值求模
IF qmz=0 && OR qmz=2 OR qmz=6 OR qmz=8  如果符合这四个约定条件之一,就进行相应工作.如果一个也没有符合条件的,直接使记录指针向下移动一个(SKIP)
EXIT                                &&因为符合条件,则做完相应工作后跳出内循环
ENDIF
SKIP                                &&素数表指针向下移动一个
ENDFOR
IF k>jlh
exit
ENDIF
ENDFOR
IF j>zs
SELECT 2              &&打开保存求解结果的信息表
APPEND BLANK                        &&增加一条空记录
REPLACE 奇数 WITH i && 把bpz赋给素数        
endif
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是寻找不能被表示的奇数程序。
#138
独木星空2021-10-17 06:49
回复 137楼 独木星空
在vb6版块,风吹过b版主已经给出了vb6代码。为了暂时不掩盖他的发帖,没有在那里及时回帖致谢。
#139
独木星空2021-10-17 06:53
SELECT 1
USE D:\方程p减2的n次方\素数表万.DBF ALIAS 素数表万
SELECT 2
USE D:\方程p减2的n次方\一加m表.DBF ALIAS 一加m表
kssj=SECONDS()                      &&取出开始时间
FOR i=69 TO 99 STEP 2
@12,10 SAY i
IF MOD(i,3)=0
s=3
ELSE
s=1
ENDIF
IF MOD(i,5)=0
w=5
ELSE
w=1
ENDIF
IF MOD(i,7)=0
q=7
ELSE
q=1
ENDIF
IF MOD(i,11)=0
yy=11
ELSE
yy=1
ENDIF
IF MOD(i,13)=0
ys=13
ELSE
ys=1
ENDIF
IF MOD(i,17)=0
yq=17
ELSE
yq=1
ENDIF
IF MOD(i,19)=0
yj=19
ELSE
yj=1
ENDIF
IF MOD(i,23)=0
es=23
ELSE
es=1
ENDIF
IF MOD(i,29)=0
ej=29
ELSE
ej=1
ENDIF
IF MOD(i,31)=0
sy=31
ELSE
sy=1
ENDIF
FOR j=10 TO 12000 STEP 2
@22,20 SAY j
   IF MOD(j,i)=0
   LOOP
   ENDIF
  IF MOD(j,s)=0 AND s>1
  LOOP
 ENDIF
 IF MOD(j,w)=0 AND w>1
  LOOP
 ENDIF
  IF MOD(j,q)=0 AND q>1
  LOOP
 ENDIF
  IF MOD(j,yy)=0 AND yy>1
  LOOP
 ENDIF
 IF MOD(j,ys)=0 AND ys>1
  LOOP
 ENDIF
  IF MOD(j,yq)=0 AND yq>1
  LOOP
 ENDIF
  IF MOD(j,yj)=0 AND yj>1
  LOOP
 ENDIF
 IF MOD(j,es)=0 AND es>1
  LOOP
 ENDIF
 IF MOD(j,ej)=0 AND ej>1
  LOOP
 ENDIF
 IF MOD(j,sy)=0 AND sy>1
  LOOP
 ENDIF
  SELECT 1
  GO 1
  COUNT ALL FOR 素数<=j/i TO tj
  SELECT 1
  GO 1
        FOR k=1 TO tj
        SELECT 1
        ss=素数
        jl=recno()
        pdz=j-i*ss
           SELECT 1
           GO 1
           COUNT NEXT i*tj+10 FOR 素数=pdz TO tj1  
           IF tj1=1
           EXIT
           ENDIF
         SELECT 1
        GO jl+1
        ENDFOR
   IF k>tj
   SELECT 2  
   APPEND BLANK            
   REPLACE m值 WITH i
   REPLACE n值 WITH j
   ENDIF
  ENDFOR
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是求3-99以内方程无素解的程序,方程为x+my=N,x,y为素数,m为小于100的奇数。
#140
独木星空2021-10-17 06:57
SELECT 1
USE D:\方程p减2的n次方\素数表万.DBF ALIAS 素数表万
SELECT 2
USE D:\方程p减2的n次方\一加m表.DBF ALIAS 一加m表
kssj=SECONDS()                      &&取出开始时间
FOR i=70 TO 100 STEP 2
@12,10 SAY i
IF MOD(i,3)=0
s=3
ELSE
s=1
ENDIF
IF MOD(i,5)=0
w=5
ELSE
w=1
ENDIF
IF MOD(i,7)=0
q=7
ELSE
q=1
ENDIF
IF MOD(i,11)=0
yy=11
ELSE
yy=1
ENDIF
IF MOD(i,13)=0
ys=13
ELSE
ys=1
ENDIF
IF MOD(i,17)=0
yq=17
ELSE
yq=1
ENDIF
IF MOD(i,19)=0
yj=19
ELSE
yj=1
ENDIF
IF MOD(i,23)=0
es=23
ELSE
es=1
ENDIF
IF MOD(i,29)=0
ej=29
ELSE
ej=1
ENDIF
IF MOD(i,31)=0
sy=31
ELSE
sy=1
ENDIF
FOR j=9 TO 13999 STEP 2
@22,20 SAY j
   IF MOD(j,i)=0
   LOOP
   ENDIF
  IF MOD(j,s)=0 AND s>1
  LOOP
 ENDIF
 IF MOD(j,w)=0 AND w>1
  LOOP
 ENDIF
  IF MOD(j,q)=0 AND q>1
  LOOP
 ENDIF
  IF MOD(j,yy)=0 AND yy>1
  LOOP
 ENDIF
 IF MOD(j,ys)=0 AND ys>1
  LOOP
 ENDIF
  IF MOD(j,yq)=0 AND yq>1
  LOOP
 ENDIF
  IF MOD(j,yj)=0 AND yj>1
  LOOP
 ENDIF
 IF MOD(j,es)=0 AND es>1
  LOOP
 ENDIF
 IF MOD(j,ej)=0 AND ej>1
  LOOP
 ENDIF
 IF MOD(j,sy)=0 AND sy>1
  LOOP
 ENDIF
  SELECT 1
  GO 1
  COUNT ALL FOR 素数<=j/i TO tj
  SELECT 1
  GO 1
        FOR k=1 TO tj
        SELECT 1
        ss=素数
        jl=recno()
        pdz=j-i*ss
           SELECT 1
           GO 1
           COUNT NEXT i*tj+10 FOR 素数=pdz TO tj1  
           IF tj1=1
           EXIT
           ENDIF
         SELECT 1
        GO jl+1
        ENDFOR
   IF k>tj
   SELECT 2  
   APPEND BLANK            
   REPLACE m值 WITH i
   REPLACE n值 WITH j
   ENDIF
  ENDFOR
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是求2-100以内方程无素解的程序,方程为x+my=N,x,y为素数,m为小于101的偶数。
laowan001先生如果看到,请把条件语句改写成数组,从素数3到31部分,跳出进入下一个,同时改写。提前向laowan001先生致谢。
#141
独木星空2021-10-17 10:00
SELECT 1
USE  D:\方程p减2的n次方\素数表万.DBF ALIAS 素数表万
SELECT 2
USE D:\方程p减2的n次方\一加m表.DBF ALIAS 一加m表
kssj=SECONDS()                      &&取出开始时间
FOR i=70 TO 100 STEP 2
@12,10 SAY i
IF MOD(i,3)=0
s=3
ELSE
s=1
ENDIF
IF MOD(i,5)=0
w=5
ELSE
w=1
ENDIF
IF MOD(i,7)=0
q=7
ELSE
q=1
ENDIF
IF MOD(i,11)=0
yy=11
ELSE
yy=1
ENDIF
IF MOD(i,13)=0
ys=13
ELSE
ys=1
ENDIF
IF MOD(i,17)=0
yq=17
ELSE
yq=1
ENDIF
IF MOD(i,19)=0
yj=19
ELSE
yj=1
ENDIF
IF MOD(i,23)=0
es=23
ELSE
es=1
ENDIF
IF MOD(i,29)=0
ej=29
ELSE
ej=1
ENDIF
IF MOD(i,31)=0
sy=31
ELSE
sy=1
ENDIF
IF MOD(i,37)=0
sq=37
ELSE
sq=1
ENDIF
IF MOD(i,41)=0
ssy=41
ELSE
ssy=1
ENDIF
IF MOD(i,43)=0
sss=43  &&原设计为ss=43,因为主循环中,此变量已经付给素数=ss,造成多重编码变量,导致结果运行错误
ELSE
sss=1   &&同上解释
ENDIF
IF MOD(i,47)=0
ssq=47
ELSE
ssq=1
ENDIF
FOR j=9 TO 13999 STEP 2
@22,20 SAY j
   IF MOD(j,i)=0
   LOOP
   ENDIF
  IF MOD(j,s)=0 AND s>1
  LOOP
 ENDIF
 IF MOD(j,w)=0 AND w>1
  LOOP
 ENDIF
  IF MOD(j,q)=0 AND q>1
  LOOP
 ENDIF
  IF MOD(j,yy)=0 AND yy>1
  LOOP
 ENDIF
 IF MOD(j,ys)=0 AND ys>1
  LOOP
 ENDIF
  IF MOD(j,yq)=0 AND yq>1
  LOOP
 ENDIF
  IF MOD(j,yj)=0 AND yj>1
  LOOP
 ENDIF
 IF MOD(j,es)=0 AND es>1
  LOOP
 ENDIF
 IF MOD(j,ej)=0 AND ej>1
  LOOP
 ENDIF
 IF MOD(j,sy)=0 AND sy>1
  LOOP
 ENDIF
 IF MOD(j,sq)=0 AND sq>1
  LOOP
 ENDIF
 IF MOD(j,ssy)=0 AND ssy>1
  LOOP
 ENDIF
 IF MOD(j,sss)=0 AND sss>1 &&原设计为ss=43,因为主循环中,此变量已经付给素数=ss,造成多重编码变量,导致结果运行错误
  LOOP
 ENDIF
  IF MOD(j,ssq)=0 AND ssq>1
  LOOP
 ENDIF
SELECT 1
 GO 1
  COUNT ALL FOR 素数<=j/i TO tj
  SELECT 1
  GO 1
        FOR k=1 TO tj
        SELECT 1
        ss=素数
        jl=recno()
        pdz=j-i*ss
           SELECT 1
           GO 1
           COUNT NEXT i*tj+10 FOR 素数=pdz TO tj1  
           IF tj1=1
           EXIT
           ENDIF
         SELECT 1
        GO jl+1
        ENDFOR
   IF k>tj
   SELECT 2  
   APPEND BLANK            
   REPLACE m值 WITH i
   REPLACE n值 WITH j
   ENDIF
  ENDFOR
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
当m为偶数时,对于大于72的偶数,需用本程序才正确。大于100后仍就不正确。
对于43这个变量名称做了调整,因为与素数=ss相同。

[此贴子已经被作者于2021-10-17 12:32编辑过]

#142
laowan0012021-10-17 10:01
回复 140楼 独木星空
这种情况用数组不合适,用临时表吧
没有数据无法测试

程序代码:
SELECT 1
USE D:\方程p减2的n次方\素数表万.DBF ALIAS 素数表万
SELECT 2
USE D:\方程p减2的n次方\一加m表.DBF ALIAS 一加m表
kssj=SECONDS()                      &&取出开始时间

CREATE CURSOR S31 (模数 int,值 int)
INSERT INTO S31 (模数) VALUES (3)
INSERT INTO S31 (模数) VALUES (5)
INSERT INTO S31 (模数) VALUES (7)
INSERT INTO S31 (模数) VALUES (11)
INSERT INTO S31 (模数) VALUES (13)
INSERT INTO S31 (模数) VALUES (17)
INSERT INTO S31 (模数) VALUES (19)
INSERT INTO S31 (模数) VALUES (23)
INSERT INTO S31 (模数) VALUES (29)
INSERT INTO S31 (模数) VALUES (31)

FOR i=70 TO 100 STEP 2
@12,10 SAY i
    UPDATE s31 SET=1
    UPDATE s31 SET=模数 WHERE MOD(i,模数)=0

IF .F.    && 被替代的部分
    IF MOD(i,3)=0
        s=3
    ELSE
        s=1
    ENDIF
    IF MOD(i,5)=0
        w=5
    ELSE
        w=1
    ENDIF
    IF MOD(i,7)=0
        q=7
    ELSE
        q=1
    ENDIF
    IF MOD(i,11)=0
        yy=11
    ELSE
        yy=1
    ENDIF
    IF MOD(i,13)=0
        ys=13
    ELSE
        ys=1
    ENDIF
    IF MOD(i,17)=0
        yq=17
    ELSE
        yq=1
    ENDIF
    IF MOD(i,19)=0
        yj=19
    ELSE
        yj=1
    ENDIF
    IF MOD(i,23)=0
        es=23
    ELSE
        es=1
    ENDIF
    IF MOD(i,29)=0
        ej=29
    ELSE
        ej=1
    ENDIF
    IF MOD(i,31)=0
        sy=31
    ELSE
        sy=1
    ENDIF
ENDIF    && 被替代的部分结束

FOR j=9 TO 13999 STEP 2
@22,20 SAY j

   IF MOD(j,i)=0
       LOOP
   ENDIF

    SELECT s31
    locate for>1 AND mod(j,值)=0
    if !eof()
        loop
    endif

IF .f.        && 被替代的部分
    IF MOD(j,s)=0 AND s>1
    LOOP
    ENDIF

 IF MOD(j,w)=0 AND w>1
  LOOP

 ENDIF
  IF MOD(j,q)=0 AND q>1
  LOOP

 ENDIF
  IF MOD(j,yy)=0 AND yy>1
  LOOP

 ENDIF

 IF MOD(j,ys)=0 AND ys>1
  LOOP

 ENDIF
  IF MOD(j,yq)=0 AND yq>1
  LOOP

 ENDIF
  IF MOD(j,yj)=0 AND yj>1
  LOOP

 ENDIF

 IF MOD(j,es)=0 AND es>1
  LOOP

 ENDIF

 IF MOD(j,ej)=0 AND ej>1
  LOOP

 ENDIF

 IF MOD(j,sy)=0 AND sy>1
  LOOP

 ENDIF

 
ENDIF         && 被替代的部分,结束

 
  SELECT 1
  GO 1
  COUNT ALL FOR 素数<=j/i TO tj
  SELECT 1
  GO 1
        FOR k=1 TO tj
        SELECT 1
        ss=素数
        jl=recno()
        pdz=j-i*ss
           SELECT 1
           GO 1
           COUNT NEXT i*tj+10 FOR 素数=pdz TO tj1  
           IF tj1=1
           EXIT
           ENDIF
         SELECT 1
        GO jl+1
        ENDFOR
   IF k>tj
   SELECT 2  
   APPEND BLANK            
   REPLACE m值 WITH i
   REPLACE n值 WITH j
   ENDIF
  ENDFOR
ENDFOR

USE IN s31    && 关闭临时表

=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是求2-100以内方程无素解的程序,方程为x+my=N,x,y为素数,m为小于101的偶数。
laowan001先生如果看到,请把条件语句改写成数组,从素数3到31部分,跳出进入下一个,同时改写。提前向laowan001先生致谢。


[此贴子已经被作者于2021-10-17 13:48编辑过]

#143
独木星空2021-10-17 12:36
回复 142楼 laowan001
再次,谢谢!laowan001先生给提的建议,和改造。
#144
laowan0012021-10-17 13:49
142楼程序有问题,已经修改了
#145
独木星空2021-10-20 23:34
这个问题可以画上句号了。因为没有人再给出新的算法。
#146
独木星空2021-10-22 07:49
回复 45楼 laowan001
SELECT [ALLI DISTINCT TTOP nExpr PERCENT Select List Item L]
FROM IFORCE Table tist ItemL](WITH (BUFFERING -JExpr[oinType]JOIN DatabaseName!]Table [[AS] LocalAlias]
ION JoinCondition [ANDI OR [oinCondition i
FilterConditionl ... IWHERE JoinCondition|
FilterCondition [ANDIOR JoinCondition!
FilterCondition]..]
[GROUP BY Column_List Item [....]]
HAVING FilterCondition [ANDIOR ...JI UNION [ALLJ SELECTCommand]
IORDER BY Order Item [ASC| DESC] L...J]
[StorageDestinationDisplayDestination]
PREFERENCE PreferenceName] [NOCONSOLE IPLAINJ INOWAIT
JoinType-INNERILEFT!RIGHTIFULL [OUTER]
StorageDestination-INTO [ARRAY ArrayNameI
CURSOR CursorName[NOFILTERIREADWRITE]!TABLE TableName]
DisplayDestination-TO [FILE FileName [ADDITIVE]I PRINTER PROMPTIISCREEN]
SELECT nWorkAreacTableAlias
分界
[ all i distinct ttop nexpr percent select list item l ](with (buffering-jexpr [ ointype ] join databasename!)
合并条件,合并条件,合并条件,合并条件,合并条件![过滤条件]。.][按列列表项目[ ... ]]具有过滤条件[和... 联合[所有选择命令]按订单项目
[ asc | desc ] l。.[ storagedestationdisplaydestination ] preference preferencename ][ noconsole iplainj inowait jointype-inileft![ outer ]
storagedestination-into [ array arraynamei cursor cursorname [ nofilterireadwrite ] ![ table tablename ] displaydestination-to [ file filename [ additive ] i printer promptiiscreen ]
选择 nworkareactablealias
分界
[ALLI DISTINCT TTOP nExpr PERCENT Select List Item L]
FROM IFORCE Table tist ItemL](WITH (BUFFERING -JExpr[oinType]JOIN DatabaseName!]
所有我不同的 ttop nexpr 百分比选择列表项目 lfrom iforce 表存储项目与缓冲-jexpr ointype 连接数据库名称!
分界
[ asc | desc ] l。.[ storagedestationdisplaydestination ] preference preferencename ][ noconsole iplainj inowait jointype-inileft![ outer ]
storagedestination-into [ array arraynamei cursor cursorname [ nofilterireadwrite ] ![ table tablename ] displaydestination-to [ file filename [ additive ] i printer promptiiscreen ]
因此,选择目的地的偏好应该选择不同的控制台,不要选择等待连接类型!外部存储目的地-到数组数组名称光标修改名称 nofilterireadwrite 表格名称显示目的地-到文件名添加物 i printer promptiiscreen
这是laowan001先生算法中,所用到语句,用在线翻译,获得大概内容,仅仅一个语句,所包含的内容却很强大,无奈自己英语水平,白纸一张,翻译成汉语,倒是可以知道大概意思。
#147
独木星空2021-10-23 23:21
回复 45楼 laowan001
如果这是一道高考作文题,laowan001先生可以得100分,因为他用到了所给的提示素材,没有跑题。
#148
独木星空2021-10-23 23:27
回复 87楼 吹水佬
吹水佬版主的dll文件,在运行速度上堪称一流。但是如果这个问题,是一道高考作文题,恐怕阅卷老师,只能忍疼割爱,评个不及格分数,原因是,根本就没有用到所给的素材,全凭自己的任意发挥了,也就是说,已经跑题了。
#149
吹水佬2021-10-24 05:51
以下是引用独木星空在2021-10-23 23:27:23的发言:

吹水佬版主的dll文件,在运行速度上堪称一流。但是如果这个问题,是一道高考作文题,恐怕阅卷老师,只能忍疼割爱,评个不及格分数,原因是,根本就没有用到所给的素材,全凭自己的任意发挥了,也就是说,已经跑题了。

这个dll应该是答题内容的第一段落,何来跑题?
一开始题目就不完整,表述不清晰,探讨问题无概念、无方向、无目的,试问谁会花时间去答理。
见你一直在自问自答,也不知你到底想做什么,其间就提问过几句,想理清一下思路,看看有无其他方式方法能达到相同目的算法。一落笔写下的那个dll就是这个意思。
好可惜,我真的审错题了,原来题目要求是无讨论空间,一定要按出题目人的思路走。
因方向不明、目的不确,我怕死路一条不敢走下去了。

[此贴子已经被作者于2021-10-24 11:24编辑过]

#150
吹水佬2021-10-24 09:44
吹水佬只会吹水,再多吹几下。
1、其实,我一直有关注这个问题,只是找不到互动交换意见讨论下去的机会。
2、有一点不明白,在VB版块也见到你提出同样的问题,想必是想用VB编程来解决问题,VB是不能直接使用你的DBF,说明你是想变通。要变通,就有可能要跑题,所以跑题未必是坏事。
3、至于你提到那个dll不能在其他模块或其他程序使用,我可以明确说明一下:只要能调用windows API的程序在任何地方都能使用这个dll。
4、至于我提到的“必要性”和“充分性”问题,如:
   只是简单地给出:2,3,5,7  那只是很有限的必要性。
   如果能给出:2,3,5,7,...,n  就能体验充分性。因没有见到这种形式的出现,所以就说是:谈不上有充分性。
   如果这个 n 没确定,对于这个问题,可以说目的就不明确,这个n对算法来说是很重要。

#151
独木星空2021-10-24 15:06
回复 150楼 吹水佬
先从第四点,说起:这个问题无非就是做个多么大的筛子,它仍就没有离开筛法的本质。在以2为周期时,只有2n-1,可能是素数;当增到周期6时,即能过素数2,和3的式子,只有6n-5,6n-1,两个式子;当把素数5也拽进来时,只有1,7,11,13,17,19,23,29这八类式子,它们加30n,一直都会有素数产生;说白了,就是素数连成积(素数阶乘)的互质数,所形成的多项式,210n+与210互质的数,共有(2-1)*(3-1)*(5-1)*(7-1)=48个,素数只能在这48个多项式式子中产成,.....,我的筛子,做到2*3*5*7*11*13*17=510510,一个周期的跨度就是510510个,自然数。所需要判断2*4*6*10*12*16=92160个数值,是否为素数,10个外循环,就可以跨过510510*10=5105100个自然数,需要判断92160*10=921600个数是否为素数。这里有个关键性问题,不是一个一个的判断,是否为素数,而是,一次性判断整个区间段内数,是否为素数,这里的一个外循环,是要判断92160个数是否为素数。当然,筛子还可以做大些,根据需要而定。
     那个数据源表,就是一个提前做出来的一个筛子。
     当然这种做法,就一定会用到素数表,所以计划筛选多大范围,就需要其平方根前的素数表。
再说一下,第三点,我的意思不是那种的应用嫁接,还是用它处理同样的问题:
      例如能过素数2,3,5的孪生素数对,(0,2),过素数2时,剩余1个可选,过素数3时,仍就一个可选(因为0除3余数为0,被占用,2除3余数为2,余数2被占用,只有模3余1的余数未被占用);(0,2)过素数5的关卡时,余数0,及余数2被占用,余数1,3,4可取,周期2*3*5=30,(2-1)*(3-2)*(5-2)=3,也就是说,在30周期这个跨度内,只有三个数可以通过:分别为1,13,19.
素数    2    3    5
0    0    0    0
2    0    2    2
剩余余数类    1    1    1
剩余余数类            3
剩余余数类            4
横竖说明    对素数2    对素数3    对素数5
选项            1
选项            7
选项        1    13
选项    1    3    19
选项    2    5    25
可选项    1    1    1
可选项            13
可选项            19
如果不去专门研究,或许得好好理解一下,在30以内,只有30n+1,30n+13,30n+19这三个式子可以产生孪生素数对(用最后一个表示)。
当扩展到,素数7时,仍就需要去掉余数0及余数2,那么30*7=210内,符合条件的,有3*(7-2)=15个式子,可以产生孪生素数对,
周期210    0    30    60    90    120    150    180
1    1    31    61    91    121    151    181
13    13    43    73    103    133    163    193
19    19    49    79    109    139    169    199
先按素数5时,周期30,向后扩展,3*7=21个元素,其中有3*2=6个元素,过不了素数7的关卡。即上边模7余数为0,或者2的。
周期210    0    30    60    90    120    150    180
1    1    31    61    0    0    151    181
13    13    43    73    103    0    0    193
19    19    0    0    109    139    169    199
模7余数是0或2的数置数成0,其余的照搬。
1234