标题:编写一个程序求Q(奇数)减2的n次方其值没有素数的奇数
只看楼主
独木星空
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
结帖率:100%
已结贴  问题点数:40 回复次数:34 
编写一个程序求Q(奇数)减2的n次方其值没有素数的奇数
猜想每一个奇数(大于等于5的)都可以表示成一个素数+2^n形式,编写一个vb6程序,寻找一亿内的反例。例如1048573这个数,它小于2^20=1048576,也就是1048573-2^n这个式子中的n可以从1取到19,在这19次取值中,其结果假设没有素数,则次数是一个反例,其中有一次是素数,就不是反例,程序设计中,也可以考虑,当为真时,跳出循环,执行下一个奇数。最好先制作素数表,或许也不快,不如直接判断,比起判断一个数是否为素数要容易的多(是指运算时间上)。大概就这么个意思,有不清楚的地方,在商榷。
搜索更多相关主题的帖子: 素数 编写 次方 判断 奇数 
2021-10-15 18:53
独木星空
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
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,"运行时间提示")
这是用vfp语言编写的寻找不能被表示的奇数。

素数问题的解决是我学习编程永恒的动力。
2021-10-16 05:40
独木星空
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
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,"运行时间提示")
这是用vfp语言编写的制作能被表示的奇数。

素数问题的解决是我学习编程永恒的动力。
2021-10-16 05:42
独木星空
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
回复 楼主 独木星空
希望大家献计献策,把这个问题解决了,用vb6语言,不胜感激。

素数问题的解决是我学习编程永恒的动力。
2021-10-16 05:43
独木星空
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:河北省曲阳县
等 级:版主
威 望:57
帖 子:713
专家分:556
注 册:2016-6-29
得分:0 
这个版块太冷清了。

素数问题的解决是我学习编程永恒的动力。
2021-10-16 15:51
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:30 
先传一个 手动验算的 excle 文档。先看看是不是这样的。
excle 中素数表,只给到了 1万以内,所以手动验算也只能在1万以内




没有素数的奇数.zip (20.91 KB)




授人于鱼,不如授人于渔
早已停用QQ了
2021-10-16 18:56
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
程序代码:
Option Explicit
Dim Ssb() As Long            '素数表,1亿以内素数表,一共5761455个
Dim ssbj As Long
Dim b2b(30) As Long         '2的倍数表,long 范围最大只能容纳 2^31,但最后一个数用不了,会超范围

Const 范围 As Long = 10000  '1亿以内,我光生成素数表就用了超过4分钟。你要测试1亿,直接把这1万改成1亿吧

Private Sub Command1_Click()
Dim i As Long, j As Long, o As Long, t As Long
Dim fly As Boolean, flj As Long, fl() As Long

flj = 0
ReDim fl(flj)

Call 日志("开始生成素数表")
Call 生成素数表

Call 日志("开始生成2的倍数表")
Call 生成倍数表

Call 日志("开始计算....")

For i = 5 To 范围 Step 2
    j = 1
    fly = False             '假设不符合
    Do While i > Ssb(j)
        t = i - Ssb(j)
        For o = 0 To 30         '这里会浪费循环次数,不管了
            If t = b2b(o) Then
                fly = True      '找到符合
                Exit For        '不再查找
            End If
        Next o
        If fly Then Exit Do     '找到符合不再查找
        j = j + 1
    Loop
    If Not fly Then             '如果都没找到
        flj = flj + 1           '保存结果
        ReDim Preserve fl(flj)
        fl(flj) = i
        Call 日志("找到第 " & flj & " 个: " & i)        '显示结果,注意 日志过程中有 DoEvents 命令,会拖慢运算速度
    End If
Next i

Call 日志("完成查找,共找到 " & flj & " 个。")

End Sub

Private Sub 生成倍数表()
'如果有倍数表,则不再生成
If b2b(30) > 0 Then Exit Sub

Dim i As Long
For i = 0 To 30
    b2b(i) = 2 ^ i
Next i
End Sub

Private Sub 生成素数表()
'如果已经有素数表,则不再生成
If ssbj > 3 Then Exit Sub

Dim i As Long, j As Long, t As Long
Dim sy As Boolean

'素数从2开始,需要指定
ssbj = 1
ReDim Ssb(ssbj)
Ssb(1) = 2

For i = 3 To 范围 Step 2
    sy = True
    t = Sqr(i)
    For j = 3 To ssbj
        If t < Ssb(j) Then Exit For
        If i Mod Ssb(j) = 0 Then
            sy = False
            Exit For
        End If
    Next j
    If sy Then
        ssbj = ssbj + 1
        ReDim Preserve Ssb(ssbj)
        Ssb(ssbj) = i
    End If
Next i
End Sub

Private Sub 日志(cs As String)
    With List1
        If .ListCount >= 100 Then
            .RemoveItem 0
        End If
        .AddItem Now & " " & cs
        DoEvents
    End With
End Sub

授人于鱼,不如授人于渔
早已停用QQ了
2021-10-16 19:05
ysr2857
Rank: 6Rank: 6
等 级:贵宾
威 望:28
帖 子:767
专家分:65
注 册:2020-2-10
得分:10 
回复 7楼 风吹过b
Private Sub 日志(cs As String)
    With List1‘(试验显示list1变量未定义,无法运行,再学习一下)
        If .ListCount >= 100 Then
            .RemoveItem 0
        End If
        .AddItem Now & " " & cs
        DoEvents
    End With
End Sub
2021-10-17 15:45
ysr2857
Rank: 6Rank: 6
等 级:贵宾
威 望:28
帖 子:767
专家分:65
注 册:2020-2-10
得分:0 
回复 8楼 ysr2857
Option Explicit
Dim Ssb() As Long            '素数表,1亿以内素数表,一共5761455个
Dim ssbj As Long
Dim b2b(30) As Long         '2的倍数表,long 范围最大只能容纳 2^31,但最后一个数用不了,会超范围

Const 范围 As Long = 10000  '1亿以内,我光生成素数表就用了超过4分钟。你要测试1亿,直接把这1万改成1亿吧

Private Sub Command1_Click()
Dim i As Long, j As Long, o As Long, t As Long, ja
Dim fly As Boolean, flj As Long, fl() As Long

flj = 0
ReDim fl(flj)

Call 日志("开始生成素数表")
Call 生成素数表

Call 日志("开始生成2的倍数表")
Call 生成倍数表

Call 日志("开始计算....")

For i = 5 To 范围 Step 2
    j = 1
    fly = False             '假设不符合
    Do While i > Ssb(j)
        t = i - Ssb(j)
        For o = 0 To 30         '这里会浪费循环次数,不管了
            If t = b2b(o) Then
                fly = True      '找到符合
                Exit For        '不再查找
            End If
        Next o
        If fly Then Exit Do     '找到符合不再查找
        j = j + 1
    Loop
    If Not fly Then             '如果都没找到
        flj = flj + 1           '保存结果
        ReDim Preserve fl(flj)
        fl(flj) = i
        Call 日志("找到第 " & flj & " 个: " & i)        '显示结果,注意 日志过程中有 DoEvents 命令,会拖慢运算速度
    End If
Next i

Call 日志("完成查找,共找到 " & flj & " 个。")
Text1 = flj
End Sub

Private Sub 生成倍数表()
'如果有倍数表,则不再生成
If b2b(30) > 0 Then Exit Sub

Dim i As Long
For i = 0 To 30
    b2b(i) = 2 ^ i
Next i
End Sub

Private Sub 生成素数表()
'如果已经有素数表,则不再生成
If ssbj > 3 Then Exit Sub

Dim i As Long, j As Long, t As Long, ja
Dim sy As Boolean

'素数从2开始,需要指定
ssbj = 1
ReDim Ssb(ssbj)
Ssb(1) = 2

For i = 3 To 范围 Step 2
    sy = True
    t = Sqr(i)
    For j = 3 To ssbj
        If t < Ssb(j) Then Exit For
        If i Mod Ssb(j) = 0 Then
            sy = False
            Exit For
        End If
    Next j
    If sy Then
        ssbj = ssbj + 1
        ReDim Preserve Ssb(ssbj)
        Ssb(ssbj) = i
         ja = " " & i '增加一条
    End If
Next i
End Sub

Private Sub 日志(cs As String)
Dim s$, i%, j, ja
Dim list1
s = Mid(ja, 2) '修改的部分
j = Split(s)
For i = 0 To UBound(j)
list1.AddItem j(i)
cs = " " & j(i)
Next
   
End Sub

改成这样后结果是:Text1=26.不知道结果对不对?(可能是不对,这样程序可以运行了,当输出改为Text1=i时,Text1=10001)

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

2021-10-17 17:00
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
回复 8楼 ysr2857
list1 是需要要窗体上自己再放一个控件,这个控件显示 运行日志用的,程序里限制不超过100条记录。


授人于鱼,不如授人于渔
早已停用QQ了
2021-10-17 19:26



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




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

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