1 / 34

418115: การโปรแกรมโครงสร้าง คำสั่ง while (2)

418115: การโปรแกรมโครงสร้าง คำสั่ง while (2). ประมุข ขันเงิน pramook@gmail.com. โปรแกรมเช็คจำนวนเฉพาะ. ให้ผู้ใช้ป้อนจำนวนเต็มบวกมาหนึ่งตัว แล้วบอกว่ามันเป็นจำนวนเฉพาะหรือไม่ Enter n: 2 2 is a prime number. Enter n: 7 7 is a prime number. Enter n: 6 6 is not a prime number.

isha
Download Presentation

418115: การโปรแกรมโครงสร้าง คำสั่ง while (2)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 418115: การโปรแกรมโครงสร้างคำสั่ง while (2) ประมุข ขันเงิน pramook@gmail.com

  2. โปรแกรมเช็คจำนวนเฉพาะโปรแกรมเช็คจำนวนเฉพาะ • ให้ผู้ใช้ป้อนจำนวนเต็มบวกมาหนึ่งตัว • แล้วบอกว่ามันเป็นจำนวนเฉพาะหรือไม่ Enter n: 2 2 is a prime number. Enter n: 7 7 is a prime number. Enter n: 6 6 is not a prime number.

  3. จำนวนเฉพาะ • จำนวนเฉพาะคืออะไร? • จำนวนเต็มบวก (ฉะนั้นไม่นับ 0 หรือจำนวนเต็มลบ) • ไม่ใช่จำนวนเต็มลบ • แยกตัวประกอบไม่ได้ • กล่าวคือ จำนวนเต็มบวกที่หารมันลงตัวมีเพียงแค่สองตัว คือ 1 กับตัวมันเอง • เช็คว่าจำนวนเป็นจำนวนเฉพาะได้อย่างไร? • สมมติว่าจำนวนที่เราต้องการเช็คคือ n • จำนวนที่หารมันได้มีแค่สองตัวคือ 1 กับ n • ดังนั้น 2, 3, 4, …, n-1 ต้องหารมันไม่ลงตัว • ฉะนั้นเราเช็ค 2, 3, 4, …, n-1 ทีละตัวว่าหาร n ลงตัวหรือไม่? • มีสักตัวที่หารลงตัว  ไม่ใช่จำนวนเฉพาะ • ไม่มีสักตัวที่หารลงตัว  เป็นจำนวนเฉพาะ

  4. ออกแบบโปรแกรม • รับ n • ตั้งลูปโดยใช้ k เป็นตัวแปร counter • k มีค่า 2 ถึง n-1 • สำหรับ k แต่ละค่าเช็คว่า n % k == 0 หรือไม่? • ถ้าใช่ ให้จำไว้ว่ามีเลขหารลงตัว • หลังจากลูปเสร็จการทำงาน ให้ไปเช็คว่ามีเลขหารลงตัวหรือไม่ • ถ้าใช่ แสดงว่าไม่เป็นจำนวนเฉพาะ • ถ้าไม่ใช่ แสดงว่าเป็นจำนวนเฉพาะ

  5. ลูป intis_prime=1; intk=2; while(k<n) { if(n%k==0) is_prime=0; k++; }

  6. ทั้งโปรแกรม #include <stdio.h> intmain() { intn; printf("Enter n: "); scanf("&d",&n); intis_prime=1; intk=2; while(k<n){ if(n%k==0) is_prime=0; k++; } if(is_prime&&n!=1) printf("%d is a prime number.\n",n); else printf("%d is not a prime number.\n",n); return0; }

  7. คำสั่ง break • เคยเจอมาแล้วในคำสั่ง switch • สามารถใส่ไว้ตรงในก็ได้ในส่วนที่เป็นคำสั่งที่ต้องการวนซ้ำใน คำสั่ง while • เมื่อเจอคำสั่ง break แล้วลูป while จะเลิกการทำงานทันที • มักใช้ควบคู่กับคำสั่ง if เสมอ

  8. โปรแกรมเช็คจำนวนเฉพาะโปรแกรมเช็คจำนวนเฉพาะ • เราไม่จำเป็นต้องให้ k มีค่าตั้งแต่ 2 ถึง n-1 เสมอ • ถ้ามีเลขสักตัวหารลงตัว แสดงว่าไม่ใช่จำนวนเฉพาะแล้วดังนั้นไม่มีความจำเป็นต้องเช็คจำนวนอื่นอีก • เราต้องการหยุดการทำงานของลูปทันทีที่ n%k == 0 • สามารถใช้คำสั่ง break ได้ในกรณีนี้

  9. ลูปใหม่ที่เร็วขึ้น intis_prime=1; intk=2; while(k<n) { if(n%k==0) { is_prime=0; break; } k++; }

  10. โปรแกรมสำหรับแยกตัวประกอบโปรแกรมสำหรับแยกตัวประกอบ • รับจำนวนเต็มหนึ่งตัวจากผู้ใช้ • แยกตัวประกอบของจำนวนเต็มที่ผู้ใช้ให้มา Enter a positive integer: 128 128 = 2 * 2 * 2 * 2 * 2 * 2 * 2 Enter a positive integer: 365 365 = 5 * 73 Enter a positive integer: 97 97 = 97

  11. การแยกตัวประกอบ • แยกตัวประกอบคืออะไร? • การเขียนจำนวนเต็มอยู่ในรูปผลคูณของจำนวนเฉพาะ • ทำอย่างไรดีถึงจะแยกได้ • สมมติว่าเลขที่เราต้องการจะแยกตัวประกอบคือ n • สมมติให้ n > 1 (กรณี n = 1 ไม่มีอะไร) • หาจำนวนเฉพาะมาสักตัวที่หาร n ลงตัว • สมมติว่าจำนวนเฉพาะนี้คือ p • ถ้าจำนวนเฉพาะนั้นหาร n ลงตัว เราก็พิมพ์มัน • แล้วลบมันออกจากตัวประกอบของ n ด้วยการสั่ง n = n/p

  12. การแยกตัวประกอบ • 48 • หาร 2 ลงตัว • 48  24 • 24 • หาร 2 ลงตัว • 24  12 • 12 • หาร 2 ลงตัว • 12  6 • 6 • หาร 2 ลงตัว • 6  3 • 3 • หาร 3 ลงตัว • 3  1 • จบการทำงาน

  13. หาจำนวนเฉพาะที่หาร n ลงตัว • สมมติว่า n > 1 • ลองเปลี่ยนคำถามเป็นว่า “จำนวนเฉพาะที่น้อยที่สุดที่หาร n ลงตัวคืออะไร?” • สังเกต คำถามนี้มีคำตอบเดียวกับคำถามที่ว่า“จำนวนที่น้อยที่สุดที่มากกว่า 1 ที่หาร n ลงตัวคืออะไร?”

  14. หาจำนวนเฉพาะที่หาร n ลงตัว • ทำไม? • สมมติว่า m เป็นจำนวนที่น้อยที่สุดที่มากกว่า 1 ที่หาร n ลงตัว • สมมติอีกว่า m ไม่ใช่จำนวนเฉพาะ • แสดงว่า m ตัวแยกตัวประกอบได้ สมมติให้ p เป็นจำนวนเฉพาะที่หาร m ลงตัว • เรารู้ว่า p < m และ p > 1 • แต่ p ก็หาร n ลงตัว • ฉะนั้น m ไม่ใช่จำนวนที่น้อยที่สุดที่มากกว่า 1 ที่หาร n ลงตัว • เกิดข้อขัดแย้ง

  15. หาจำนวนเฉพาะที่หาร n ลงตัว • หาจำนวนเฉพาะที่น้อยที่สุดที่หาร n ลงตัวคือการหาจำนวนที่มากกว่า 1 ที่น้อยที่สุดที่หาร n ลงตัว • หาอย่างไร? • เริ่มจาก p = 2 • เช็คว่า n%p == 0 หรือไม่? • ถ้าใช่ก็จบ • ถ้าไม่ใช่ก็เพิ่มค่า p ขึ้นหนึ่ง

  16. หาจำนวนเฉพาะที่หาร n ลงตัว intp=2; while(n%p!=0) p++;

  17. ลูป • หา p หนึ่งตัวที่หาร n ลงตัว • พิมพ์ p • ลบ p ออกจากความเป็นตัวประกอบของ n • n = n/p • หยุดเมื่อไหร่? • n == 1

  18. ลูป printf("%d = ",n); while(n>1) { intp=2; while(n%p!=0) p++; if(n/p==1) printf("%d\n",p); else printf("%d * ",p); n=n/p; }

  19. ทั้งโปรแกรม #include <stdio.h> intmain() { intn; printf("Enter a positive integer: "); scanf("&d",&n); if(n==1) printf("1 = 1\n"); else{ printf("%d = ",n); while(n>1){ intp=2; while(n%p!=0) p++; if(n/p==1) printf("%d\n",p); else printf("%d * ",p); n=n/p; } } return0; }

  20. เลขพาลินโดรม • เลขพาลินโดรมคือเลขที่เขียนจากหลังไปหน้าแล้วมีค่าเท่าเดิม • เช่น 12321 เป็นเลขพาลินโดรม • แต่ 123 ไม่ใช่ เพราะ 123 ไม่เท่ากับ 321 • สังเกตว่าเลขพาลินโดรมจะต่อท้ายด้วย 0 ไม่ได้

  21. โปรแกรมตรวจสอบเลขพาลินโดรมโปรแกรมตรวจสอบเลขพาลินโดรม • อ่านจำนวนเต็มบวกจากผู้ใช้หนึ่งตัว • ชนิด int • ไม่เกิน 6 หลัก • แล้วบอกว่าเลขนั้นเป็นพาลินโดรมหรือไม่ Enter n: 12321 12321 is a palindrome Enter n: 4567 4567 is not a palindrome

  22. ออกแบบโปรแกรม • พาลินโดรมคืออะไร? • เขียนกลับหลังแล้วได้ตัวเติม • จะทดสอบพาลินโดรมอย่างไร? • ก็ลองเขียนกลับหลังดูแล้วเทียบว่าเท่ากับตัวเดิมหรือไม่

  23. เขียนกลับหลัง • สมมติว่ามีเลข n =123456 • สามารถเขียนกลับหลังโดยการมีเลขอีก 1 ตัว ตอนแรกเป็น 0 • กระบวนการ • n = 123456 m = 0 • n = 12345 m = 6 • n = 1234 m = 65 • n = 123 m = 654 • n = 12 m = 6543 • n = 1 m = 65432 • n = 0 m = 654321

  24. เขียนกลับหลัง • ในแต่ละขั้น • ดึงตัวหลังของ n ออกมา • เอาตัวหลังของ n ไปต่อท้าย m • ลบตัวหลังออกจาก n • กล่าวคือ intd=n%10; n=n/10; m=m*10+d; • หยุดเมื่อใด? • เมื่อ n = 0

  25. เขียนกลับหลัง intm=0; while(n>0) { intd=n%10; n=n/10; m=m*10+d; }

  26. ทั้งโปรแกรม #include <stdio.h> intmain() { intn; printf("Enter n: "); scanf("%d",&n); intnn=n; intm=0; while(n>0){ intd=n%10; n=n/10; m=m*10+d; } if(m==nn) printf("%d is a palindrome\n",nn); else printf("%d is not a palindrome\n",nn); return0; }

  27. คำถาม • ในจำนวนเต็มตั้งแต่ 1 ถึง 1,000,000 มีจำนวนเต็มกี่ตัวที่เป็นทั้ง • จำนวนเฉพาะ และ • พาลินโดรม? • จำนวนเต็มเหล่านั้นคืออะไรบ้าง?

  28. ออกแบบโปรแกรม • เรารู้วิธีเช็คพาลินโดรม • เรารู้วิธีเช็คจำนวนเฉพาะ • ฉะนั้นเอาจำนวนเต็มมาทีละตัวแล้วเช็คว่ามันเป็นทั้งสองอย่างหรือไม่ • แล้วก็นับจำนวนที่ใช่

  29. ลูป intn=2; while(n<=999999) { [ตรวจว่า n เป็นพาลินโดรมหรือไม่] [ตรวจว่า n เป็นจำนวนเฉพาะหรือไม่] [ถ้าใช่ทั้งคู่พิมพ์ n] }

  30. ลูป (ฉบับเต็ม) intn=2; while(n<=999999){ intm=0; intnn=n; while(nn>0){ intd=nn%10; nn=nn/10; m=m*10+d; } intis_palindrome=(m==n); intis_prime=1; intk=2; while(k<n){ if(n%k==0){ is_prime=0; break; } k++; } if(is_palindrome&&is_prime) printf("%d\n",n); n++; }

  31. ปัญหา • มันช้า • ทำไม? • การเช็คจำนวนเฉพาะ • ถ้าจะเช็คว่า 983,139 เป็นจำนวนเฉพาะหรือไม่จะต้องวนรอบทั้งหมดกี่รอบ? • อาจจะถึง 983,137 รอบ! • ฉะนั้นกรณีเลวสุดโปรแกรมจะต้องวนรอบประมาณ 1,000,000 * 1,000,000 (แต่ความจริงน้อยกว่านี้มาก)

  32. ทำให้มันเร็วขึ้น? • การเช็คจำนวนเฉพาะช้า • ต้องพยายามหลีกเลี่ยง • เราสนใจเฉพาะเลขที่เป็นทั้งพาลินโดรมและจำนวนเฉพาะ • ดังนั้นถ้าเลขใดไม่เป็นพาลินโดรมแล้วเราก็ไม่ต้องไปเช็คว่ามันเป็นจำนวนเฉพาะก็ได้

  33. คำสั่ง continue • เมื่อสั่งแล้วจะไปเริ่มต้นลูปใหม่อีกครั้งหนึ่ง • ข้ามคำสั่งส่วนที่เหลือของลูปไป • มักใช้ควบคู่กับคำสั่ง if

  34. หลีกเลี่ยงการเช็คจำนวนเฉพาะหลีกเลี่ยงการเช็คจำนวนเฉพาะ intn=2; while(n<=999999){ intm=0; intnn=n; while(nn>0){ intd=nn%10; nn=nn/10; m=m*10+d; } intis_palindrome=(m==n); if(!is_palindrome){ n++; continue; } intis_prime=1; intk=2; while(k<n){ if(n%k==0) { is_prime=0; break; } k++; } if(is_palindrome&&is_prime) printf("%d\n",n); n++; }

More Related