อัลกอริทึมเร็วที่สุดในการค้นหาหมายเลขเฉพาะคืออะไร


183

อัลกอริทึมที่เร็วที่สุดในการค้นหาหมายเลขเฉพาะด้วย C ++ คืออะไร ฉันใช้อัลกอริทึมของตะแกรง แต่ฉันยังต้องการให้เร็วขึ้น!


พบบทความเก่า แต่ดูน่าสนใจ: สนุกกับตัวเลขที่สำคัญ
Mvcoile

29
@Jaider การดำเนินการนี้ล้มเหลวสำหรับตัวเลขที่ต่ำถึง 7 (111) นอกจากนี้ยังล้มเหลวสำหรับ 1001 = 9 และเห็นได้ชัดว่ามันล้มเหลวสำหรับช่วงเวลาเกือบทั้งหมดโดยทั่วไป (ไม่ครอบคลุมกรณี 2 ^ p - 1 ซึ่งเป็นหมายเลขเฉพาะของ Mersenne - ตัวอย่างที่สร้างแบบคลาสสิก - ซึ่งจะอยู่ในรูปแบบ 111 ... 1)
Daniel Kats

1
@Kasperasky - คุณไม่ได้พูดถึงตะแกรงใด? คุณอาจหมายถึง Sieve of Eranthoses!
user2618142

อัลกอริทึมของ Eratosthenes
Emad Aghayi

คำตอบ:


79

การดำเนินไปอย่างรวดเร็วมากของตะแกรงของแอทคินแดน Bernstein ของprimegen ตะแกรงนี้จะมีประสิทธิภาพมากขึ้นกว่าตะแกรงของ Eratosthenes หน้าของเขามีข้อมูลมาตรฐานบางอย่าง


10
จริงๆแล้วฉันไม่คิดว่าไพรม์เจนนั้นเร็วที่สุดหรือเร็วที่สุดเป็นอันดับสอง ฉันคิดว่า yafu และ primesieve เร็วขึ้นกว่า 2 ^ 32 อย่างแน่นอน ทั้งสองแบบ (แก้ไข) ตะแกรงของ Eratosthenes มากกว่า Atkin-Bernstein ตะแกรง
ชาร์ลส์

5
Primesieve Sieve of Eratosthenes (SoE) เป็นอัลกอริทึมที่เร็วที่สุดที่เป็นไปได้และจะเร็วกว่าการใช้ Sieve of Atkin SoA รวมถึง Bernstein ที่เชื่อมโยงในคำตอบนี้เพราะ primesieve ลดจำนวนการดำเนินการเมื่อเทียบกับ SoA: สำหรับ 32- ช่วงหมายเลขบิต (2 ^ 32 - 1), primesieve ทำประมาณ 1.2 ล้าน culls ในขณะที่ SoA ทำรวมสลับกันประมาณ 1.4 พันล้านครั้งรวมกับการสลับระหว่างการดำเนินการกับสี่เหลี่ยมจัตุรัสซึ่งทั้งสองการดำเนินการมีความซับซ้อนเดียวกันและสามารถปรับให้เหมาะสมในเรื่องเดียวกัน ทาง
GordonBGood

7
ต่อ: Bernstein เปรียบเทียบ SoE ​​โดยใช้การแยกตัวประกอบวงล้อที่มีประสิทธิภาพเช่นเดียวกับ SoA ซึ่งคือ 2; 3; 5 wheel การใช้วงล้อนั้นส่งผลให้มีจำนวน 1.83 ล้านล้านตัวในช่วงจำนวน 32 บิต; สิ่งนี้ทำให้ SoA เร็วขึ้นประมาณ 30% เมื่อเปรียบเทียบรุ่นที่ จำกัด ของ SoEเพื่อการเพิ่มประสิทธิภาพอื่น ๆ ที่เทียบเท่า อย่างไรก็ตามอัลกอริทึม primesieve ใช้ 2; 3; 5; 7 wheel ร่วมกับ 2; 3; 5; 7; 11; 13; 13; 17 วงล้อก่อนตัดเพื่อลดจำนวนของการดำเนินการประมาณ 1.2 พันล้านเพื่อทำงานเกี่ยวกับ เร็วกว่า SoA 16.7% พร้อมการปรับลูปการทำงานที่เทียบเท่า
GordonBGood

6
ต่อเนื่อง 2: SOA con ไม่มีการแยกตัวประกอบวงล้อด้วยปัจจัยที่สูงกว่าที่ใช้เพื่อสร้างความแตกต่างอย่างมากในขณะที่ 2; 3; 5 วงล้อแยกตัวประกอบที่ 5 เป็นส่วนที่ "อบเข้า" ของอัลกอริทึม
GordonBGood

4
@Eamon Nerbonne, WP ถูกต้อง; อย่างไรก็ตามการมีความซับซ้อนในการคำนวณที่ดีขึ้นเล็กน้อยไม่ได้ทำให้อัลกอริทึมเร็วขึ้นสำหรับการใช้งานทั่วไป ในความคิดเห็นเหล่านี้ฉันหมายถึงการแยกตัวประกอบวงล้อสูงสุดของ Sieve of Eratosthenes (SoE) (ซึ่งเป็นไปไม่ได้สำหรับ Sieve of Atkin-SoA) ทำให้การดำเนินงานของ SoE ลดลงเล็กน้อยจนถึงระดับประมาณหนึ่งพันล้าน โดยทั่วไปแล้วเราจำเป็นต้องใช้การแบ่งส่วนหน้าเพื่อเอาชนะข้อ จำกัด ด้านหน่วยความจำและนั่นคือจุดที่ SoA ล้มเหลวทำให้มีค่าใช้จ่ายคงที่เพิ่มขึ้นอย่างรวดเร็วเมื่อเพิ่มช่วง
GordonBGood

29

หากจะต้องเร็วมากคุณสามารถรวมรายการช่วงเวลา:
http://www.bigprimes.net/archive/prime/

หากคุณเพียงแค่ต้องรู้ว่าถ้าจำนวนหนึ่งเป็นจำนวนเฉพาะมีต่าง ๆการทดสอบที่สำคัญที่ระบุไว้ในวิกิพีเดีย อาจเป็นวิธีที่เร็วที่สุดในการพิจารณาว่าจำนวนมากนั้นเป็นเฉพาะช่วงเวลาหรือไม่โดยเฉพาะอย่างยิ่งเพราะพวกเขาสามารถบอกคุณได้ว่าจำนวนนั้นไม่ใช่จำนวนเฉพาะหรือไม่


2
รายการของช่วงเวลาทั้งหมดหรือไม่ ฉันคิดว่าคุณหมายถึงรายการในไม่กี่ช่วงแรก ... :)
j_random_hacker

9
ถ้าคุณโทรไป 100000000 สักสองสามข้อก็ใช่ :)
Georg Schölly

58
แน่นอนว่า 100000000 คือ "ไม่กี่" เมื่อเทียบกับอินฟินิตี้;)
Timofey

9
ทำไมคุณคิดว่า Sieve of Atkin (SoA) เร็วกว่า Sieve of Eratosthenes (SoE) แน่นอนว่าไม่ใช่เมื่อใช้โปรแกรมที่ใช้รหัสหลอกเหมือนในบทความ Wikipedia ที่คุณเชื่อมโยง หากมีการใช้งาน SoE ในระดับที่ใกล้เคียงกับการเพิ่มประสิทธิภาพที่เป็นไปได้เช่นเดียวกับที่ใช้กับ SoA แสดงว่ามีการดำเนินการน้อยกว่าเล็กน้อยสำหรับช่วง sieving ที่มีขนาดใหญ่มากสำหรับ SoA มากกว่าสำหรับ SOE แต่กำไรนั้นมักจะชดเชยมากกว่าด้วยความซับซ้อนที่เพิ่มขึ้น ค่าใช้จ่ายปัจจัยคงที่พิเศษเพิ่มเติมของความซับซ้อนในการคำนวณเช่นนี้สำหรับการใช้งานจริง SOE จะดีกว่า
GordonBGood

26

เขาเขาฉันรู้ว่าฉันเป็นหมอผีคำถามตอบคำถามเก่า แต่ฉันเพิ่งพบคำถามนี้ค้นหาสุทธิเพื่อหาวิธีที่จะใช้การทดสอบหมายเลขเฉพาะที่มีประสิทธิภาพ

จนถึงตอนนี้ฉันเชื่อว่าอัลกอริทึมการทดสอบจำนวนเฉพาะที่เร็วที่สุดคือ Strong Probable Prime (SPRP) ฉันอ้างจากฟอรัม Nvidia CUDA:

หนึ่งในปัญหาเฉพาะที่ใช้งานได้จริงในทฤษฎีจำนวนนั้นเกี่ยวข้องกับการระบุหมายเลขเฉพาะ เมื่อพิจารณาจาก N คุณจะทราบได้อย่างมีประสิทธิภาพว่าดีหรือไม่? นี่ไม่ได้เป็นเพียงปัญหาที่เกิดขึ้นจริงมันอาจเป็นของจริงที่จำเป็นในโค้ดบางทีเมื่อคุณต้องการค้นหาขนาดแฮชของตารางที่สำคัญในช่วงที่กำหนด ถ้า N เป็นบางสิ่งบางอย่างตามคำสั่งของ 2 ^ 30 คุณต้องการทำการทดสอบ 30,000 ครั้งเพื่อค้นหาปัจจัยใด ๆ หรือไม่? เห็นได้ชัดว่าไม่

วิธีแก้ปัญหาที่ใช้งานได้จริงสำหรับปัญหานี้คือการทดสอบอย่างง่าย ๆ ที่เรียกว่าการทดสอบ Prime Prime ที่น่าจะเป็นออยเลอร์ นี่คือการทดสอบที่สำหรับจำนวนเต็ม N ที่น่าจะเป็นไปได้ว่าเป็นประเภทเฉพาะหรือไม่และการทดสอบซ้ำ ๆ สามารถเพิ่มความน่าจะเป็นของความถูกต้องได้ ส่วนที่ช้าของการทดสอบนั้นส่วนใหญ่เกี่ยวข้องกับการคำนวณค่าที่คล้ายกับโมดูโล A ^ (N-1) N. ใครก็ตามที่ใช้การเข้ารหัสคีย์สาธารณะของ RSA ได้ใช้อัลกอริธึมนี้ มันมีประโยชน์ทั้งสำหรับจำนวนเต็มขนาดใหญ่ (เช่น 512 บิต) เช่นเดียวกับ 32 หรือ 64 บิตปกติ

การทดสอบสามารถเปลี่ยนจากการปฏิเสธความน่าจะเป็นการพิสูจน์แบบดั้งเดิมโดยการคำนวณพารามิเตอร์อินพุตการทดสอบบางอย่างซึ่งเป็นที่ทราบกันว่าประสบความสำเร็จสำหรับช่วงของ N แต่น่าเสียดายที่การค้นพบ "การทดสอบที่รู้จักกันดีที่สุด" เหล่านี้ ในความเป็นจริงไม่มีที่สิ้นสุด) โดเมน ในปี 1980 รายการแรกของการทดสอบที่มีประโยชน์ถูกสร้างขึ้นโดย Carl Pomerance (มีชื่อเสียงในการเป็นปัจจัยหนึ่งของ RSA-129 ด้วยอัลกอริทึม Seive Quadratic Seive ของเขา) ภายหลัง Jaeschke ปรับปรุงผลลัพธ์อย่างมีนัยสำคัญในปี 1993 ในปี 2004 จางและ Tang และข้อ จำกัด ของโดเมนการค้นหา Greathouse และ Livingstone ได้เปิดตัวผลการค้นหาที่ทันสมัยที่สุดจนถึงขณะนี้บนเว็บที่http://math.crg4.com/primes.htmlผลลัพธ์ที่ดีที่สุดของโดเมนการค้นหาขนาดใหญ่

ดูที่นี่สำหรับข้อมูลเพิ่มเติม: http://primes.utm.edu/prove/prove2_3.htmlและhttp://forums.nvidia.com/index.php?showtopic=70483

หากคุณต้องการวิธีในการสร้างจำนวนเฉพาะจำนวนมากและไม่สนใจที่จะสร้างหมายเลขเฉพาะทั้งหมด <จำนวนเต็ม n คุณสามารถใช้การทดสอบ Lucas-Lehmer เพื่อตรวจสอบหมายเลขเฉพาะของ Mersenne หมายเลขเฉพาะ Mersenne อยู่ในรูปแบบ 2 ^ p -1 ฉันคิดว่าการทดสอบ Lucas-Lehmer เป็นอัลกอริทึมที่เร็วที่สุดที่ค้นพบสำหรับหมายเลขเฉพาะของ Mersenne

และถ้าคุณไม่เพียง แต่ต้องการใช้อัลกอริธึมที่เร็วที่สุด แต่ยังเป็นฮาร์ดแวร์ที่เร็วที่สุดให้ลองติดตั้งโดยใช้ Nvidia CUDA เขียนเคอร์เนลสำหรับ CUDA และรันบน GPU

คุณสามารถหาเงินได้แม้หากคุณพบจำนวนเฉพาะจำนวนมากพอ EFF กำลังให้รางวัลตั้งแต่ $ 50K ถึง $ 250K: https://www.eff.org/awards/coop


17

มีการทดสอบทางคณิตศาสตร์ 100% ที่จะตรวจสอบว่ามีจำนวนเป็นPเป็นสำคัญหรือคอมโพสิตเรียกว่าAKS Primality ทดสอบ

แนวคิดนั้นง่าย: ให้ตัวเลขPถ้าสัมประสิทธิ์(x-1)^P - (x^P-1)ทั้งหมดหารด้วยPแล้วPก็เป็นจำนวนเฉพาะมิฉะนั้นจะเป็นจำนวนประกอบ

ตัวอย่างเช่นที่กำหนดP = 3จะให้พหุนาม:

   (x-1)^3 - (x^3 - 1)
 = x^3 + 3x^2 - 3x - 1 - (x^3 - 1)
 = 3x^2 - 3x

และสัมประสิทธิ์นั้นหารด้วย3ดังนั้นจำนวนจึงเป็นจำนวนเฉพาะ

และตัวอย่างที่P = 4ซึ่งไม่ได้เป็นนายกจะให้:

   (x-1)^4 - (x^4-1)
 = x^4 - 4x^3 + 6x^2 - 4x + 1 - (x^4 - 1)
 = -4x^3 + 6x^2 - 4x

และตรงนี้เราจะเห็นได้ว่าสัมประสิทธิ์6ไม่หารด้วย4ดังนั้นมันจึงไม่สำคัญ

พหุนาม(x-1)^Pจะเป็นP+1คำและสามารถพบได้โดยใช้ชุดค่าผสม ดังนั้นการทดสอบนี้จะรันในO(n)รันไทม์ดังนั้นฉันไม่รู้ว่าจะมีประโยชน์แค่ไหนเพราะคุณสามารถทำซ้ำได้iตั้งแต่ 0 ถึงpและทดสอบส่วนที่เหลือ


5
AKS เป็นวิธีการที่ช้ามาก ๆ ในทางปฏิบัติไม่ใช่การแข่งขันกับวิธีอื่น ๆ วิธีที่คุณอธิบายไม่ใช่ AKS แต่เป็นบทแทรกเปิดที่ช้ากว่าการแบ่งการทดลองที่ไม่ได้เพิ่มประสิทธิภาพ (ตามที่คุณชี้ให้เห็น)
DanaJ

สวัสดี @Kousha คำxย่อหมายถึงอะไร? ใน(x-1)^P - (x^P-1). คุณมีรหัสตัวอย่างสำหรับสิ่งนี้หรือไม่? ใน C ++ สำหรับการพิจารณาว่าจำนวนเต็มหรือไม่?
kiLLua

@kiLLua X เป็นเพียงตัวแปร มันคือสัมประสิทธิ์ของ X ที่พิจารณาว่าตัวเลขนั้นเป็นจำนวนเฉพาะหรือไม่ และไม่ฉันไม่มีรหัส ฉันไม่แนะนำให้ใช้วิธีนี้ในการพิจารณาว่าตัวเลขนั้นดีหรือไม่ นี่เป็นเพียงพฤติกรรมทางคณิตศาสตร์ที่ยอดเยี่ยมของจำนวนเฉพาะ แต่อย่างอื่นมันไม่มีประสิทธิภาพอย่างไม่น่าเชื่อ
Kousha

5

เป็นปัญหาของคุณในการตัดสินใจว่าหมายเลขเฉพาะเป็นนายกหรือไม่ ถ้าอย่างนั้นคุณต้องมีการทดสอบเบื้องต้น (ง่าย) หรือคุณต้องการเวลาทั้งหมดถึงจำนวนที่กำหนด? ในกรณีที่ตัวกรองแบบนายกนั้นดี (ง่าย แต่ต้องการหน่วยความจำ) หรือคุณต้องการปัจจัยสำคัญของตัวเลข? สิ่งนี้จะต้องมีการแยกตัวประกอบ (ยากสำหรับคนจำนวนมากถ้าคุณต้องการวิธีที่มีประสิทธิภาพมากที่สุด) ตัวเลขที่คุณดูมีขนาดใหญ่แค่ไหน 16 บิต 32 บิต ใหญ่?

วิธีหนึ่งที่ชาญฉลาดและมีประสิทธิภาพคือการคำนวณตารางช่วงเวลาล่วงหน้าและเก็บไว้ในไฟล์โดยใช้การเข้ารหัสระดับบิต ไฟล์นั้นถือเป็นเวกเตอร์บิตยาวหนึ่งอันในขณะที่บิต n แทนเลขจำนวนเต็ม n ถ้า n เป็นไพรม์บิตจะถูกตั้งค่าเป็นหนึ่งและเป็นศูนย์มิฉะนั้น การค้นหารวดเร็วมาก (คุณคำนวณไบต์ออฟเซตและบิตมาสก์) และไม่ต้องการโหลดไฟล์ในหน่วยความจำ


การทดสอบแบบดั้งเดิมที่ดีนั้นสามารถแข่งขันได้กับความหน่วงแฝงของหน่วยความจำหลักสำหรับตารางสำคัญที่เหมาะสมพอสมควรดังนั้นฉันจะไม่ใช้สิ่งนี้ยกเว้นว่าจะเหมาะกับ L2
ชาร์ลส์

3

Rabin-Millerเป็นการทดสอบความน่าจะเป็นแบบดั้งเดิม (คุณเรียกใช้เป็น K คูณและหมายเลขอินพุทอาจประกอบกันอย่างแน่นอนหรืออาจเป็นข้อผิดพลาดที่น่าจะเป็นข้อผิดพลาด 4 -K (ซ้ำสองสามร้อยครั้งและเกือบจะบอกความจริงกับคุณ)

มีที่ไม่น่าจะเป็น (กำหนด) เป็นตัวแปรของราบินมิลเลอร์

มหาราชอินเทอร์เน็ตเซนเนนายกค้นหา (Gimps) ซึ่งได้พบบันทึกของโลกสำหรับการพิสูจน์ที่สำคัญที่สุด (2 74207281 - 1 ณ มิถุนายน 2017) จะใช้ขั้นตอนวิธีการหลายแต่เหล่านี้เป็นจำนวนเฉพาะในรูปแบบพิเศษ อย่างไรก็ตามหน้า GIMPS ด้านบนไม่รวมการทดสอบเบื้องต้นแบบกำหนดแน่นอนทั่วไป ดูเหมือนว่าจะระบุว่าอัลกอริทึมใดที่ "เร็วที่สุด" ขึ้นอยู่กับขนาดของจำนวนที่จะทดสอบ หากหมายเลขของคุณพอดีกับ 64 บิตคุณอาจไม่ควรใช้วิธีที่มีเป้าหมายเพื่อกำหนดจำนวนหลักล้านหลายหลัก


2

ขึ้นอยู่กับใบสมัครของคุณ มีข้อควรพิจารณาบางอย่าง:

  • คุณต้องการเพียงแค่ข้อมูลว่าตัวเลขสองสามตัวนั้นมีความสำคัญหรือไม่คุณต้องการตัวเลขที่สำคัญทั้งหมดถึงขีด จำกัด ที่กำหนดหรือคุณต้องการตัวเลขที่เป็นไปได้ทั้งหมดหรือไม่
  • ตัวเลขที่คุณต้องรับมือมีจำนวนเท่าใด

การทดสอบของ Miller-Rabin และอนาล็อกนั้นเร็วกว่าตะแกรงสำหรับตัวเลขที่มีขนาดที่แน่นอน ด้านล่างนั้นใช้แผนกทดลอง (ถ้าคุณมีตัวเลขไม่กี่ตัว) หรือตะแกรงจะเร็วกว่า


-1

ฉันมักจะใช้วิธีนี้ในการคำนวณจำนวนเฉพาะตามด้วยอัลกอริทึมตะแกรง

void primelist()
 {
   for(int i = 4; i < pr; i += 2) mark[ i ] = false;
   for(int i = 3; i < pr; i += 2) mark[ i ] = true; mark[ 2 ] = true;
   for(int i = 3, sq = sqrt( pr ); i < sq; i += 2)
       if(mark[ i ])
          for(int j = i << 1; j < pr; j += i) mark[ j ] = false;
  prime[ 0 ] = 2; ind = 1;
  for(int i = 3; i < pr; i += 2)
    if(mark[ i ]) ind++; printf("%d\n", ind);
 }

-1

ฉันจะให้คุณตัดสินใจว่ามันเร็วที่สุดหรือไม่

using System;
namespace PrimeNumbers
{

public static class Program
{
    static int primesCount = 0;


    public static void Main()
    {
        DateTime startingTime = DateTime.Now;

        RangePrime(1,1000000);   

        DateTime endingTime = DateTime.Now;

        TimeSpan span = endingTime - startingTime;

        Console.WriteLine("span = {0}", span.TotalSeconds);

    }


    public static void RangePrime(int start, int end)
    {
        for (int i = start; i != end+1; i++)
        {
            bool isPrime = IsPrime(i);
            if(isPrime)
            {
                primesCount++;
                Console.WriteLine("number = {0}", i);
            }
        }
        Console.WriteLine("primes count = {0}",primesCount);
    }



    public static bool IsPrime(int ToCheck)
    {

        if (ToCheck == 2) return true;
        if (ToCheck < 2) return false;


        if (IsOdd(ToCheck))
        {
            for (int i = 3; i <= (ToCheck / 3); i += 2)
            {
                if (ToCheck % i == 0) return false;
            }
            return true;
        }
        else return false; // even numbers(excluding 2) are composite
    }

    public static bool IsOdd(int ToCheck)
    {
        return ((ToCheck % 2 != 0) ? true : false);
    }
}
}

ใช้เวลาประมาณ 82 วินาทีในการค้นหาและพิมพ์ตัวเลขสำคัญในช่วง 1 ถึง 1,000,000 บนแล็ปท็อป Core 2 Duo ของฉันพร้อมโปรเซสเซอร์ 2.40 GHz และพบว่ามีจำนวนเฉพาะ78,498ตัว


3
นี่เป็นวิธีที่ช้าเกินไป i <= (ToCheck / 3)ปัญหาคือ i <= (ToCheck / i)มันควรจะเป็น ด้วยมันอาจทำงานใน 0.1 วินาทีแทน
Will Ness

-3
#include<stdio.h>
main()
{
    long long unsigned x,y,b,z,e,r,c;
    scanf("%llu",&x);
    if(x<2)return 0;
    scanf("%llu",&y);
    if(y<x)return 0;
    if(x==2)printf("|2");
    if(x%2==0)x+=1;
    if(y%2==0)y-=1;
    for(b=x;b<=y;b+=2)
    {
        z=b;e=0;
        for(c=2;c*c<=z;c++)
        {
            if(z%c==0)e++;
            if(e>0)z=3;
        }
        if(e==0)
        {
            printf("|%llu",z);
            r+=1;
        }
    }
    printf("|\n%llu outputs...\n",r);
    scanf("%llu",&r);
}    

r ถูกใช้ก่อนที่จะเริ่มต้น
zumalifeguard

-3

ฉันไม่รู้เกี่ยวกับอัลกอริทึมที่กำหนดไว้ล่วงหน้า แต่ฉันสร้างของตัวเองซึ่งเร็วมาก สามารถประมวลผลตัวเลข 20 หลักในเวลาน้อยกว่า 1 วินาที ความสามารถสูงสุดของโปรแกรมนี้คือ 18446744073709551615 โปรแกรมคือ:

#include <iostream>
#include <cmath>
#include <stdlib.h>

using namespace std;

unsigned long long int num = 0;

bool prime() {
    if (num % 2 == 0 || num == 1) {
        return false;
    }

    unsigned long int square_root = sqrt(num);
    for (unsigned long int i = 3; i <= square_root; i += 2) {
        if (num % i == 0) {
            return false;
        }
    }

    return true;
}

int main() {
    do {
        system("cls");
        cout << "Enter number : ";
        cin >> num;

        if (prime()) {
            cout << "The number is a prime number" << endl << endl << endl << endl;
        } else {
            cout << "The number is not a prime number" << endl << endl << endl << endl;
        }
        system("pause");
    } while (1);

    return 0;
}

-4
#include <iostream>

using namespace std;

int set [1000000];

int main (){

    for (int i=0; i<1000000; i++){
        set [i] = 0;
    }
    int set_size= 1000;
    set [set_size];
    set [0] = 2;
    set [1] = 3;
    int Ps = 0;
    int last = 2;

    cout << 2 << " " << 3 << " ";

    for (int n=1; n<10000; n++){
        int t = 0;
        Ps = (n%2)+1+(3*n);
        for (int i=0; i==i; i++){
            if (set [i] == 0) break;
            if (Ps%set[i]==0){
                t=1;
                break;
            }
        }
        if (t==0){
            cout << Ps << " ";
            set [last] = Ps;
            last++;
        }
    }
    //cout << last << endl;


    cout << endl;

    system ("pause");
    return 0;
}

12
นี่ควรเป็นคำตอบสำหรับ "วิธีการเขียนโค้ดที่ไม่มีโครงสร้างโดยไม่ต้องใช้ GOTO" ความสับสนทั้งหมดนี้เพียงแค่กำหนดรหัสแผนกการทดลองง่าย ๆ ! (n%2)+1+(3*n)เป็นสิ่งที่ดีแม้ว่า :)
Will Ness

1
@ Will Ness ฉันจะลบล้างสิ่งนี้เป็นคำตอบสำหรับคำถามนั้น เหตุใดจึงใช้ a for for loop เมื่อแมโครทำ :)
Rob Grant

-4

ฉันรู้ว่ามันค่อนข้างช้า แต่สิ่งนี้มีประโยชน์สำหรับผู้ที่มาที่นี่จากการค้นหา อย่างไรก็ตามนี่คือ JavaScript บางส่วนที่ต้องอาศัยความจริงที่ว่าจะต้องมีการทดสอบเฉพาะปัจจัยสำคัญเท่านั้นดังนั้นค่า primes ก่อนหน้านี้ที่สร้างโดยรหัสนั้นจะถูกใช้อีกครั้งเพื่อใช้เป็นปัจจัยทดสอบในภายหลัง แน่นอนว่าค่าทั้งหมดและ mod 5 จะถูกกรองออกก่อน ผลลัพธ์จะอยู่ในอาร์เรย์ P และรหัสนี้สามารถกระทืบ 10 ล้านครั้งภายในเวลา 1.5 วินาทีบน i7 พีซี (หรือ 100 ล้านในประมาณ 20) เขียนใหม่ใน C ควรเร็วมาก

var P = [1, 2], j, k, l = 3

for (k = 3 ; k < 10000000 ; k += 2)
{
  loop: if (++l < 5)
  {
    for (j = 2 ; P[j] <= Math.sqrt(k) ; ++j)
      if (k % P[j] == 0) break loop

    P[P.length] = k
  }
  else l = 0
}

2
ซึ่งจะทำให้คุณจำนวนมากของปัญหาถ้าคุณกำลังสร้างจำนวนมากของจำนวนเฉพาะและสำหรับ comparations ที่ใช้ดีกว่า P [เจ] * P [เจ] <= k เพราะ sqrt ช้าสวย
ไซมอน

-11
#include<iostream>
using namespace std;

void main()
{
    int num,i,j,prime;
    cout<<"Enter the upper limit :";
    cin>>num;

    cout<<"Prime numbers till "<<num<<" are :2, ";

    for(i=3;i<=num;i++)
    {
        prime=1;
        for(j=2;j<i;j++)
        {
            if(i%j==0)
            {
                prime=0;
                break;
            }
        }

        if(prime==1)
            cout<<i<<", ";

    }
}

60
นี่เป็นเรื่องที่ช้าที่สุดที่คุณสามารถทำได้
Will Ness

1
มันช้ามากหากขีด จำกัด สูงสุดบอกว่า 10,000,000 รหัสนี้จะใช้เวลานานมาก !!
Dixit Singla

รหัสนี้คือ O (N ^ 2 / log N) หากไม่มีbreak;ก็จะช้าลง O (N ^ 2) แต่นั่นอาจถูกมองว่าเป็นข้อผิดพลาดในการเขียนโค้ดอยู่แล้ว การบันทึกและทดสอบตามช่วงเวลาคือ O (N ^ 2 / (บันทึก N) ^ 2) และการทดสอบตามช่วงเวลาด้านล่างสแควร์รูทของตัวเลขเท่านั้นคือ O (N ^ 1.5 / (บันทึก N) ^ 2)
Will Ness

@ WillNess อาจจะเกินความจริงเล็กน้อย เขาสามารถเริ่ม for for loop ได้อย่างง่ายดายจาก 1 แทน 2 และเพิ่ม j <= i แทน j <i :)
Kenny Cason

3
ฉันไม่คิดว่าควรลบโพสต์นี้ทำหน้าที่เป็นตัวอย่างที่มีคุณค่า
Will Ness
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.