用篩法求[a,b]中的素數。find out the prime numbers in [a, b].
#include
int main()
for(i=2;i<=1000;i++)}}
}for(i=a;i<=b;i++)
}
以上是用於求1到1000內素數的最原始的篩法。如果把範圍擴大到1到100,000,000,顯然陣列長度會很大而且會出現很多不必要的運算和遍歷過程。
經過思考,我主要找到兩處可以進行優化的地方。
1.假設要求10000以內的素數,因為100*100=10000,100以內的質數就足以篩掉範圍內所有合數,這樣100到10000的數沒有必要作為因數再遍歷一次。
2.按照上面這種方法,即使a和b的範圍很小或者取值都很小,還是需要將1到100,000,000的所有素數都求出來再輸出,程式幾乎不隨a和b取值不同變化。
由此,我想到了如何改進這兩個地方。
將函式分為兩部分。第一部分利用篩法求1到b的平方根的全部素數。解決了第乙個問題的同時,也使程式和b的取值建立了聯絡。第二部分利用篩法和上一步求出的素數篩出a到b內的全部合數。
#include
#include//後面要用到sqrt函式,數學函式定義在數學庫中,標頭檔案為math.h
int main()
int prime[10001],num=0;//定義新陣列,將1到b的平方根內的所有素數存到prime陣列中
for(i=2;i<=m;i++)}}
}//第一部分結束,只有prime陣列和num下一步還要用到。
int d[260001],count=1;//d的長度為a和b的最大差值
for(j=a;j<=b;j++)
//用2這個肯定存在於所有情況中的素數初始化表示a到b之間數的陣列d
//對於後面篩除a,b間所有合數這一步,需要用到的主要資料只有:作為因數的prime陣列和要被判斷的d陣列
for(i=2;i<=num;i++)
//直接跳過已經被篩除的數,減少重複運算
if(d[count]%prime[i]==0&&d[count]/prime[i]!=1)
//將能被當前prime[i]整除的數篩除,標記為0
else
count++;
} }
for(i=1;i<=(count-1);i++)
}//輸出所有沒有被標記為0的數即為素數
}
一些容易出現bug的地方:
1.注意要特殊討論1
2.count、i記數;有的時候退出迴圈前會加1,想得到的數就比輸出的少1
3.注意if,else if,else的關係;如果是if,if,else並列,如論如何都會進入else。
4.除錯時可以用1-10,90-100這兩組資料。90-100第
一、二部分都只迴圈十次。
根據這道題,我得出了一點經驗:
1.篩法中乙個重要的思想是「標記」,把陣列中某個數標記為乙個特定的值來表示這個數具有某種性質。
2.在迴圈中可以用continue跳過一些被標記的數,簡化運算。
3.可以定義一些新陣列/變數儲存有用的資料,使程式更加清晰。
素數篩法(素數篩 線性篩)
求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...
多執行緒適用於阻塞式IO場景,不適用於平行計算場景
python的標準實現是cpython。cpython執行python 分為2個步驟 首先,將文字原始碼解釋編譯為位元組碼,然後再用乙個直譯器去 解釋執行位元組碼。位元組碼直譯器是有狀態的,需要維護該狀態的一致性,因此使用了gil global interpreter lock,全域性直譯器鎖 gi...
折半查詢法(僅適用於已排好順序)
includeusing namespace std templateint binarysearch type array,int lenght,type key 不適用於char 型別 array mid key right mid 1 left mid 1 return 1 int main ...