zoukankan      html  css  js  c++  java
  • 素数的高效算法

    欢迎来我的个人网站:http://www.rxwcv.cn

    自然数(Natural Number):自然数就是正整数集合,用{1, 2, 3, ...}表示,也可以是非负整数集合,用{0, 1, 2, 3, ...}表示,前都主要用于数论,后者则主要用于数理逻辑、集合论、计算机科学等。

    素数(): 素数一个大于1的自然数,该自然数只有1它本身两个除数(自然数)。

    这概念虽然简单,但如果不知道的话程序写将无从下手,这无异于“James, 给我写个满足要求的程序", 但并没有说写什么样的程序。

    典型算法

    最简单最直接的方法应该就是用2到(n-1)的自然数去除n,其中n即为将要确实是数,如果每个数都不能整除,则说明n是素数。

    而事实上没有必要用2到(n-1)之间的每一个数去除n。例如要确实7是不是系数,用除到3的时候就已经可以确实7是系数而不必继续了,即只要用2,3去除n就可以了。一般地,只要用2到n/2的自然数去除n就可以了。这样比前面的方法要快一点。

    人们还想到了一个更好一点方法:用来取代n/2。

    今天同学考试的问题是:给定两个整数m,k,找出大于m同时也最靠近m的k个素数,用C语言实现如下:
    void findPrimeNum(int m, int k , int xx[]) {
        int i = 0, j, x = m + 1, isPrime;
        while (i < k) {
            isPrime = TRUE;
            for ( j = 2; j <= sqrt(x); j++) { // j <= 2 也行
                if ( x % j == 0 ) {
                    isPrime = FALSE;
                    break;
                } 
            }
            if (isPrime) xx[i++] = x;
            x++;
        }
    }


    更有效的算法

    如果给定一个很大的自然数要确定其是否为素数,典型算法可能要费很多的时间才能确定下来。这里有一个更好一点的算法:
    boolean isPrime(int num) {
        
        int divisor = 3;
        int testLimit = num;

        if (num % 2 == 0) return FALSE;

        while ( testLimit > divisor ) {
            if ( num % divisor == 0 ) {
                return FALSE;
            }

            testLimit = num / divisor;
            divisor += 2;
        }

        return TRUE;
    }

    参考资源

    [1]Prime number, wikipedia, http://en.wikipedia.org/wiki/Prime_number
    [2]Determine if an Integer is a prime number, 
    Toby Herring, http://www.freevbcode.com/ShowCode.asp?ID=1059

    程序实现
    清单1:C实现
    /*
    * 典型算法
    */
    #include <stdio.h>
    #include <math.h>

    #define MAX_LEN 100
    #define TRUE 1
    #define FALSE 0

    typedef int boolean;

    void findPrimeNum(int m, int k , int xx[]);
    void findPrimeNum2(int m, int k , int xx[]);
    int isPrime(int num);

    int main(void) {
        
        int m, k, i, xx[MAX_LEN], xx2[MAX_LEN];
        
        printf("输入m: ");

        scanf("%d", &m);

        do {
            
            printf("输入k (k < %d): ", MAX_LEN);
            scanf("%d", &k);

        } while (k > MAX_LEN);

        puts("运行及结果:");

        findPrimeNum (m , k , xx);
        findPrimeNum2 (m , k , xx2);

        for (i = 0; i < k ; i++) {
            printf("%d, ", xx[i]);
        }
        printf(" ");

        for (i = 0; i < k ; i++) {
            printf("%d, ", xx2[i]);
        }
        printf(" ");

        puts("结束");
        return 0;
    }


    void findPrimeNum(int m, int k , int xx[]) {

        int i = 0, j, x = m + 1, isPrime;

        while (i < k) {
            isPrime = TRUE;

            for ( j = 2; j <= sqrt(x); j++) { // j <= 2 也行
                if ( x % j == 0 ) {
                    isPrime = FALSE;
                    break;
                } 
            }

            if (isPrime) xx[i++] = x;
            
            x++;
        }
    }

    void findPrimeNum2(int m, int k , int xx[]) {

        int i = 0, j, x = m + 1;

        while ( i < k) {
            
            if (isPrime(x)) xx[i++] = x;

            x++;
        }
    }

    boolean isPrime(int num) {
        
        int divisor = 3;
        int testLimit = num;

        if (num % 2 == 0) return FALSE;

        while ( testLimit > divisor ) {
            if ( num % divisor == 0 ) {
                return FALSE;
            }

            testLimit = num / divisor;
            divisor += 2;
        }

        return TRUE;
    }


    清单2:VB实现
    Module Module1

        Sub Main()

            Dim num As Long
            num = 14
            If (IsPrime(num)) Then
                MsgBox(num & " is Prime")
            Else
                MsgBox(num & " is NOT Prime")
            End If

        End Sub

        Public Function IsPrime(ByVal TestPrime As Long) As Boolean
            Dim TestNum As Long
            Dim TestLimit As Long

            '   Eliminate even numbers
            If TestPrime Mod 2 = 0 Then Exit Function

            '   Loop through ODD numbers starting with 3
            TestNum = 3
            TestLimit = TestPrime
            Do While TestLimit > TestNum

                If TestPrime Mod TestNum = 0 Then
                    '   Uncomment this if you really want to know
                    'MsgBox("Divisible by " & TestNum)
                    Exit Function
                End If

                '   There's logic to this. Think about it.
                TestLimit = TestPrime TestNum

                '   Remember, we only bother to check odd numbers
                TestNum = TestNum + 2
            Loop

            '   If we made it through the loop, the number is a prime.
            IsPrime = True
        End Function


    End Module

    欢迎来我的个人网站:http://www.rxwcv.cn
  • 相关阅读:
    Java 7的javax.net.ssl.SSLHandshakeException
    Oracle数据泵导出数据库
    ORA-00054: 资源正忙 --锁表的解决方法
    Linux学习私人笔记-Shell基础
    Linux学习私人笔记-目录和文件的基本命令
    Linux学习私人笔记-文件基本命令
    Linux学习私人笔记-账号管理
    Linux学习私人笔记-Vim
    form提交表单时本地下载
    SQL Servel 中分页解决
  • 原文地址:https://www.cnblogs.com/Hewie/p/3677468.html
Copyright © 2011-2022 走看看