标题:用删除法编写一个制作素数表的vfp程序
只看楼主
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 57楼 吹水佬
是不用太计较速度。建立一个10亿内的素数表,一个一个的处理起来,得大概运算一个月的时间,当然建起了,可以拿来用。可是在没有建起前,又有几个人能等待的了。所以能建立分段运算是关键,把任务划分,分段运算,一次性运算无论是内存,还是运行时间都不允许。所以,从vfp表的大小,和内存的大小来考虑都不允许一次性的运算模式,10亿内有5千万多素数,vfp表可以存放,但是10亿,不用10亿,1亿就无法运行了,提示内存不足,所以还是分段计算为好,还有一个有利条件,可以同时打开4个程序运行(再多也不行,因为此时8GB内存几乎全部占用)。总起来说,不如分段运算,有更多的可操作性。
我所设计的,速度慢,关键就是数据的存储,读取上浪费了时间,能不能把一个外循环批次的数据用数组调入内存,然后对内存变量进行处理,意即调入是都为真,然后开始调入参考素数表中的素数,对它们进行从新设置,把整除的标记为假,处理完毕。把还是真的存盘,完成本次操作,进入下一个外循环即可。

素数问题的解决是我学习编程永恒的动力。
2021-09-16 05:47
schtg
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:https://t.me/pump_upp
等 级:贵宾
威 望:67
帖 子:1355
专家分:2534
注 册:2012-2-29
得分:0 
向各位大侠学习,谢谢分享!
吹版的运行确实很快的


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

2021-09-16 05:50
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 62楼 schtg
说明你的电脑配置更高。我的运行80多。

素数问题的解决是我学习编程永恒的动力。
2021-09-16 06:28
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
以下是引用独木星空在2021-9-15 19:58:10的发言:

算到N=50000000时,用时95.805秒。不过,再大,提示内存不足,不能运行。
所以用分段法还是比较适用的,把i=i+i改为mod(N,i)=0,标记为假更为适用(可能会增加时间),所用i=j变为从参照素数表中的下一个素数为好(skip),运算到本批次最大数开方值即可。
总起来说,用数据源表,参照素数表,盛放素数的表,这三个表用到了,就可以形成分段计算,用mod(N,P)=0作为标记假的条件。
那个程序以N前素数做为步长和筛选条件,每步不涉及其他非倍数的记录条(或者数组的下标),直到不大于N为止。
后种方法是每步都需要检查每一个数(可以绕开前组已经标记过的),但是它只需要到开方值即可。
吹水佬版主能不能把那个程序改成用数据源和参照素数表的程序,以便分段运算。(深层用意是把它嫁接到别的程序里去,那样的数组,及处理方式(指标记为假的条件)无法嫁接到其他程序里去)。

用吹斑竹的方法,为了避免数据很大的时候,出现问题,采取分段处理就可以了。
比如你要处理10亿个,你分成10段,每段就变成1亿了。
2021-09-16 08:44
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 59楼 laowan001
CLEAR
SELECT 1
USE D:\标记法\数据源表.DBF ALIAS 数据源
SELECT 2
USE D:\标记法\素数表5万.DBF ALIAS 素数表参
SELECT 3
USE D:\标记法\数据表a.DBF ALIAS 数据a
SELECT 5
USE D:\标记法\素数表结果.DBF ALIAS 素数表果
kssj=SECONDS()                     
FOR i=11 TO 12
   @12,10 SAY i
      SELECT 素数式+(i-1)*9699690 数据1 FROM 数据源 INTO CURSOR 数据a READWRITE
      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=素参
            SELECT 3
            jlts1=RECCOUNT()  &&把数据a表中的记录条总数赋给变量:jlts1
            GO 1
            FOR h1=1  to jlts1
            sj1=数据1
            ys1=MOD(sj1,sc)
            IF ys1=0
            SELECT 3
            DELETE next 1
            ENDIF
            SELECT 3
            SKIP
            ENDFOR
            SELECT 3
            PACK
        SELECT 2
        skip  
        ENDFOR
      
            SELECT 3
            jlts2=RECCOUNT()  &&把数据a表中的记录条总数赋给变量:jlts1
            GO 1
            FOR h2=1  to jlts2
            sj2=数据1
            SELECT 5
            APPEND BLANK
            REPLACE 素数 WITH sj2
            SELECT 3
            SKIP
            ENDFOR
 ENDFOR
 =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
把开始部分改写后,运行后提示信息:对话框标题:程序错误,内容:别名已被使用;后来把“数据源”用数字1代替,“数据a”用数字3代替;这时运行后:提示信息:SQL:找不到列"素数式"(是用单文本号括着,我打不出来)。

素数问题的解决是我学习编程永恒的动力。
2021-09-16 08:45
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
做成1个过程来调用,开始数,结束数,这样分段处理
2021-09-16 08:47
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 64楼 mywisdom88
问题的关键是不能分段。那种算法只能从1开始排列下标(数组的)。

素数问题的解决是我学习编程永恒的动力。
2021-09-16 08:52
独木星空
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 66楼 mywisdom88
对!需要把标记为假的条件,改成从参照素数表中调入的素数整倍数为假(或者余数为0的为假),也不在运算到N前,只需要到每批次的开方值前即可(回到一个一个的处理算法上,不过这里有区别,只考虑每批最大值的开方值即可,不在考虑其他的数值,再就是,原先是一个被筛选值把它开方值前的素数要用一遍(当然不是所有的是这样,只有被筛选值是素数才行,合数中间就跳出循环了);后者是一个素数把这一批数筛除一遍,接着下一个素数再把剩余的(没有被标记为假的)筛除一遍,....,一直进行下去,直到最后一个符合条件的素数参与为止)。
所以分段法,需要改变条件(标记为假的条件),这时也要用到参照素数表,和分段数据源这些表。

素数问题的解决是我学习编程永恒的动力。
2021-09-16 09:07
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用独木星空在2021-9-16 05:47:09的发言:

是不用太计较速度。建立一个10亿内的素数表,一个一个的处理起来,得大概运算一个月的时间,当然建起了,可以拿来用。可是在没有建起前,又有几个人能等待的了。

不清楚你这个素数表的实际使用情况,具体操作可能有不同的方法。
如果是对一个随机的数用查表法进行判断是不是素数,程序可以设计成自动维护这个素数表,不用先创建好这个素数表。当这个程序查表次数过程越来越多,这个素数表的数据记录就越多,程序查找素数的速度就越接近查表法的速度。

2021-09-16 09:21
laowan001
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:54
帖 子:802
专家分:1914
注 册:2015-12-30
得分:0 
回复 65楼 独木星空
程序最开始加一句
close database
就不会出“别名已被使用”了

找不到列,可能有两种原因:(1)工作区不对(2)字段名不对
2021-09-16 09:21



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




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

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