1. 程式人生 > >用VBA,MATLAB,C 從小到大生成質數表(原始碼)

用VBA,MATLAB,C 從小到大生成質數表(原始碼)

程式碼都是除錯通過的。

本演算法直接跳過了所有的偶數和個位為5的奇數,即只測試個位為1、3、7、9的整數n是不是質數。測試n是否為質數時,不是測試3~sqrt(n)之間的全部整數,而是測試3~sqrt(n)之間的全部質數,勉強算是比較高效的演算法。

Option Explicit '有很多變數本應是(長)整型,但VBA中長整型範圍只有±2^31=±2147483648,太小了
                '所以乾脆直接來Double,可達±10^308
Public dRoot As Double, obCopy As Object, sN As String, sEveryLine As String, dCurNum As Double
Public PrimeNumFileHead As Object, PrimeNumFileTail As Object, fs As Object, SavePath As String

Sub generatePrime()
Dim dRange As Double, dCount As Double

Set fs = CreateObject("scripting.filesystemobject")
SavePath = "E:\PrimeNum.txt"
Set PrimeNumFileHead = fs.createtextfile(SavePath, True)

dRange = 1000 '生成大於2且小於等於dRange的全部質數

PrimeNumFileHead.WriteLine "3"
PrimeNumFileHead.WriteLine "5"
PrimeNumFileHead.WriteLine "7"
PrimeNumFileHead.Close

Set PrimeNumFileTail = fs.OpenTextFile(SavePath, ForAppending, TristateFalse)

    For dCount = 10 To dRange - 10 Step 10
    Call TestPrime(dCount + 1)
    Call TestPrime(dCount + 3)
    Call TestPrime(dCount + 7)
    Call TestPrime(dCount + 9)
    Next

PrimeNumFileHead.Close
PrimeNumFileTail.Close
Set PrimeNumFileHead = Nothing
Set PrimeNumFileTail = Nothing
Set fs = Nothing

End Sub

Sub TestPrime(n As Double)
    sN = CStr(n)
    dRoot = Sqr(n)
    
    Set PrimeNumFileHead = fs.OpenTextFile(SavePath, ForReading, TristateFalse)
    Do While 1
        sEveryLine = PrimeNumFileHead.ReadLine '讀取一行
        dCurNum = CDbl(sEveryLine)
        If 0 = (n Mod dCurNum) Then Exit Do
            
            If dCurNum > dRoot Then
            PrimeNumFileTail.WriteLine sN '在檔案尾部追加資料
            Exit Do
            End If
    Loop
End Sub


function generatePrime(~)
clc
iRange=5000;   %生成大於2且小於等於iRange的全部質數
SavePath='E:\temp\PrimeNumber.txt';  
fpPriNumFile=fopen(SavePath,'w+');
fprintf(fpPriNumFile,'%c\n%c\n%c\n','3','5','7');
    for iCount=10:10:iRange-10
    TestPrime(iCount+1,fpPriNumFile);
    TestPrime(iCount+3,fpPriNumFile);
    TestPrime(iCount+7,fpPriNumFile);
    TestPrime(iCount+9,fpPriNumFile);
    end
fclose(fpPriNumFile);
end

function TestPrime(n,fpOpenedFile)
    fpCopy=fpOpenedFile;
    cN=int2str(n);
    dRoot=sqrt(n);
    frewind(fpOpenedFile);
        while (~feof(fpOpenedFile))
            cEveryLine=fgets(fpOpenedFile);  %讀取一行
            iCurNum=str2double(cEveryLine);
            if 0==mod(n,iCurNum)
            break;
            end
                if iCurNum>dRoot
                fseek(fpCopy,0,'eof'); %在檔案尾部追加資料
         %等價於fseek(fpCopy,0,1);
                fprintf(fpCopy,'%s\n',cN);
                break;
                end
        end
end


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    void TestPrime(unsigned long int n,FILE *fpOpenedFile);
    unsigned long int iCount,iRange=1000000;   //生成大於2且小於iRange的全部質數
    char SavePath[100]="E:\\temp\\PrimeNumber.txt";   //注意路徑的書寫格式喔!
    FILE *fpPriNumFile;
    fpPriNumFile=fopen(SavePath,"w+");
    fprintf(fpPriNumFile,"%c\n%c\n%c\n",'3','5','7');

    for(iCount=10;iCount<iRange;iCount=iCount+10)
    {
        TestPrime(iCount+1,fpPriNumFile);
        TestPrime(iCount+3,fpPriNumFile);
        TestPrime(iCount+7,fpPriNumFile);
        TestPrime(iCount+9,fpPriNumFile);
    }
    fclose(fpPriNumFile);
	if(fpPriNumFile!=NULL) free(fpPriNumFile);
    return(0);
}

void TestPrime(unsigned long int n,FILE *fpOpenedFile)
{
    FILE *fpCopy;
    fpCopy=fpOpenedFile;
    char cN[30],cEveryLine[30];
    itoa(n,cN,10);
    double dRoot;
    dRoot=sqrt(n);
    unsigned long int iCurNum;
    rewind(fpOpenedFile);
     while (!feof(fpOpenedFile))
     {
         fgets(cEveryLine,1024,fpOpenedFile);  //讀取一行
         iCurNum=atoi(cEveryLine);
            if(0==n%iCurNum)
            break;
            if(iCurNum>dRoot)
                {fseek(fpCopy,0L,2); //在檔案尾部追加資料
                 fprintf(fpCopy,"%s\n",cN);
                 break;}
     }
    if(fpOpenedFile!=NULL) free(fpOpenedFile);
    if(fpCopy!=NULL) free(fpCopy);
}