`
410063005
  • 浏览: 179979 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

算法小练习--歌德巴赫猜想

 
阅读更多

晚上没事,尝试解决一个小的算法问题。 我的算法比较弱,也没查什么参考资料,自己想的思路。肯定有更好的解法。 

 

1. 歌德巴赫猜想

所有大于等于6的偶数都可以表示成两个(奇)素数之和。
给定1-10000;要求找出每一个可以表示为两素数之和的数,如果有多对,则只需要输出其中之一即可。
输出:
N = a + b;
N=1-10000;对于不能表示的就不用输出。
a,b为两个素数。
要求:复杂度较低,代码可运行。

 

2. 思路:

1.  找到1-10000范围内的素数, 得到一个有序数组A  (时间复杂度为O(nlogn))

2.  对1-10000范围内的数进行遍历. 对每个数 i, 使用二分查找确定它在有序数组A中的"位置" pos (若存在,则为数组下标;若不存在,则为这个数插入该数组后仍能保证数组的大致位置)  (时间复杂度为O(nlogn))

3. 从有序数组A的pos位置开始,令num = A[pos],二分查找确定 i - num是否也在这个数组A中。 若在, 则表示i可以用两个素数之和表示。否则,  pos递减继续查找 (时间复杂度 O(n * n * logn) ??? )

 

第1步生成素数列表应该有更好的方法。 第3步感觉比较低效, 但实际运行时发现pos需要递减的情况比较少。也就是说,一个很大的偶数,基本上都会被分解成一个很大的素数和一个非常小的素数。下面是运行结果。


 

3.  代码

 

# encoding: utf-8
import math
from timeit import Timer
from functools import partial

# 生成素数列表
# 版本一. 比较低效
def sushu(n):
    num = 2
    alist = [2]
    
    for i in range(3, n + 1):
    
        istrue = True
        #for j in range(2, int(math.sqrt(i))):
        for j in range(2, i / 2 + 1):
            if i % j == 0:
                istrue = False
                break
        if istrue:
            alist.append(i)
    return alist
    
# 生成素数列表
# 版本二
def sushu2(n):
    num = 2
    alist = [2]
    
    for i in range(3, n + 1):
    
        istrue = True
        for j in range(2, int(math.sqrt(i)) + 1):
        #for j in range(2, i / 2):
            if i % j == 0:
                istrue = False
                break
        if istrue:
            alist.append(i)
    return alist
 
# 生成素数列表
# 版本三 
def sushu3(n):
    #num = 2
    alist = []
    
    for i in range(3, n + 1, 2):
    
        istrue = True
        for j in range(3, int(math.sqrt(i)) + 1):
        #for j in range(2, i / 2):
            if i % j == 0:
                istrue = False
                break
        if istrue:
            alist.append(i)
    return alist

# 通过二分查找找到alist中最接近 n的数的位置
def bin_search(alist, n):
    low = 0
    high = len(alist)
    
    while low < high:
        mid = low + (high - low) / 2
        if n == alist[mid]:
            return mid
        elif n < alist[mid]:
            high = mid - 1
        else:
            low = mid + 1
    return low
    
# 所有大于等于6的偶数都可以表示成两个(奇)素数之和。
def split(n):
    # 素数列表
    alist = sushu3(n)
    alist_len = len(alist)
    
    for i in range(8, n + 1, 2):
        pos = bin_search(alist, i)
        #print pos
        
        # 修正pos
        if pos >= alist_len:
            pos = alist_len - 1
        
        isok = 0
        while pos > 0:
            isok = 1
            #print pos >= alist_len
            j = i - alist[pos]
            # TODO in 是否低效
            if j in alist:
                isok = 2
                break
            pos -= 1
        '''
        if isok == 2:
            print '%d = %d + %d' %(i, alist[pos], i - alist[pos])
        elif isok == 1:
            print '%d = 不能表示' % (i)
        else:
            print '%d = 运行异常' % (i)
        '''
        
# 所有大于等于6的偶数都可以表示成两个(奇)素数之和。
def split2(n):
    # 素数列表
    alist = sushu3(n)
    alist_len = len(alist)
    
    for i in range(8, n + 1, 2):
        pos = bin_search(alist, i)
        #print pos
        
        # 修正pos
        if pos >= alist_len:
            pos = alist_len - 1
        
        isok = 0
        while pos > 0:
            isok = 1
            #print pos >= alist_len
            j = i - alist[pos]
            if j == alist[bin_search(alist, j)]:
                isok = 2
                break
            pos -= 1
        '''
        if isok == 2:
            print '%d = %d + %d' %(i, alist[pos], i - alist[pos])
        elif isok == 1:
            print '%d = 不能表示' % (i)
        else:
            print '%d = 运行异常' % (i)
        '''
        
if __name__ == '__main__':
    #print sushu(100)
    
    if False:
        t = Timer(partial(sushu, 10000))
        print t.timeit(10)
        
        t2 = Timer(partial(sushu2, 10000))
        print t2.timeit(10)        
        
        t3 = Timer(partial(sushu3, 10000))
        print t3.timeit(10)
        
    if False:
        print sushu(100)
        print sushu2(100)
        print sushu3(100)
        
    if False:
        alist = sushu3(100)
        print alist
        for x in [96, 100, 110]:
            pos = bin_search(alist, x)
            print 'pos = ', pos
            #print alist[pos - 1], alist[pos], alist[pos + 1]
        
    if True:
        t = Timer(partial(split, 10000))
        print t.timeit(10)
        
        t2 = Timer(partial(split2, 10000))
        print t2.timeit(10)        
 
  • 大小: 38.5 KB
1
5
分享到:
评论

相关推荐

    哥德巴赫猜想.rar

    哥德巴赫猜想是数学领域的一个著名未解决问题,属于数论的一部分。...虽然这个程序可能无法提供哥德巴赫猜想的证明,但它可以帮助我们理解和测试这个猜想在实际中的表现,同时也是一种有趣的数学和编程练习。

    java-chengxu.rar_哥德巴赫猜想_计算器 控制台

    在这个名为"java-chengxu.rar"的压缩包中,我们能看到几个关键的学习主题,包括哥德巴赫猜想、控制台应用以及基础语法的实践。 首先,让我们关注"哥德巴赫猜想"。这是一个著名的数学问题,它提出任何大于2的偶数都...

    归档_验证哥德巴赫猜想_

    在描述中提到的C++程序`证明哥德巴赫猜想`可能包含了以上的一种或多种算法的实现。`.xcodeproj`文件是苹果公司的Xcode开发环境的项目文件,包含了项目的源代码、资源文件、构建设置等信息。使用Xcode,学生可以编辑...

    CS-97SI:解决方案“ CS 97SI

    2262-哥德巴赫猜想-被接受 数据结构 2418-硬木树种-接受 1330-最近的共同祖先-被接受 3367-表达式-超出时间限制 动态编程 2663 -Tri Tiling-接受 1163-三角-接受 组合游戏 2234-火柴比赛-接受 基本图算法 1308-...

    全国计算机二级C常见算法整理.pdf

    - 验证哥德巴赫猜想需要对偶数分解为两个素数,通过循环和素数判断进行。 4. **排序算法**: - **选择法排序**:每一轮选择当前未排序部分的最小值,与其前一个位置的元素交换,直至完全排序。 - **冒泡法排序**...

    入门算法C语言

    以上内容总结了C语言中的一些基础算法,包括计数、求和、求阶乘、求最大公约数和最小公倍数、判断素数、验证哥德巴赫猜想以及简单的排序算法。通过这些实例的学习和练习,有助于加深对C语言的理解,并为进一步学习更...

    C常用算法[参考].pdf

    本文将详细解析C语言中常见的几种算法,包括计数、求和、求阶乘、求最大公约数与最小公倍数、判断素数以及验证哥德巴赫猜想。 首先,计数、求和、求阶乘这类简单算法通常涉及循环结构。例如,统计个位数字的出现...

    c语言几个重要算法代码

    5. **哥德巴赫猜想**: 这是一个未解的数学猜想,但C语言可以用来编写程序验证这个猜想,即任何大于2的偶数都可以表示为两个质数之和。 6. **指针移位**: C语言中的指针操作是其强大之处,通过指针移位可以高效...

    Algorithms-and-data-structures..zip_algorithms

    6. **哥德巴赫猜想**:这不是典型的计算机科学问题,但它是一个著名的数学问题。哥德巴赫猜想提出所有大于2的偶数都可以表示为两个质数之和。在编程中,这可能转化为一个搜索或验证算法,用于检查大整数是否符合这个...

    C程序设计的常用算法.docx

    哥德巴赫猜想指出,每个大于等于6的偶数都可以表示为两个素数之和。为了验证这个猜想,程序从3开始,检查每个奇数n1,看n1和n2(n2 = N - n1)是否都是素数。使用之前定义的prime函数,如果找到一组解,就打印出这两...

    C++基础-编程练习题1.pdf

    根据提供的文件信息,我们可以归纳总结出以下几个主要的知识点: ### 1. 哥德巴赫猜想 #### 知识点概述 ...这些代码片段可以作为学习C++语言的基础练习,有助于掌握基本的控制结构和算法设计思想。

    c语言练习题

    哥德巴赫猜想问题是一个数学题目,要求验证哥德巴赫猜想对 2000 以内的正偶数成立。解决这个问题需要使用数学知识,例如数论和代数。 11. 打印日历问题 知识点:算法、数据结构、计算机系统 打印日历问题是一个...

    C语言基础算法提供参考

    最后,我们提到了哥德巴赫猜想的验证,即任何大于等于6的偶数都可以表示为两个素数之和。要验证这一点,我们可以遍历所有可能的素数对,看它们的和是否等于给定的偶数。这需要结合前面的素数判断算法,对于每个偶数...

    C语言算法基础.pdf

    最后,验证哥德巴赫猜想的算法需要对大于等于6的偶数进行分解,检查每一对可能的组合是否为素数。这同样利用了`prime`函数来检查素数。从3开始,每次增加2,检查与当前数之和是否等于原始偶数,且两数是否都是素数。...

    《数据结构Java版》习题解答..doc

    - **哥德巴赫猜想**:这是一个数学问题,要求编程验证每个大于2的偶数都可以表示为两个素数之和。在Java中,可以通过遍历和素数检测算法来实现。 - **杨辉三角形**:是二项式系数的一种几何表示,可以用于学习组合...

    C语言算法总结

    5. 验证哥德巴赫猜想: 这个猜想表明任何大于等于6的偶数都可以表示为两个素数之和。为了验证这个猜想,我们可以遍历所有可能的素数对,检查它们的和是否等于给定的偶数。这里利用了`prime()`函数来判断一个数是否为...

    算法基础数论

    3. **@cfannet.com@初等数论+I(陈景润).pdf**:陈景润是中国著名的数论学家,他的著作很可能深入浅出地介绍了初等数论的各个方面,可能包含陈氏定理(哥德巴赫猜想的一部分证明)或其他著名的数论猜想。...

Global site tag (gtag.js) - Google Analytics