Skip to content

คำสั่งวนซ้ำ (Loops)

Author: Pakin Olanraktham


สมมติว่าคุณต้องการหาผลบวกของเลข \(10^6\) ตัว คุณสามารถทำได้โดยการสร้างตัวแปรมา \(10^6\) ตัว เช่น int n1, n2, n3, ..., n1000000 แล้วจากนั้นก็รับค่า \(10^6\) ตัว เช่น cin >> n1 >> n2 >> n3 >> ... >> n1000000;

แต่ผมเชื่อว่าคุณคงไม่ขยันขนาดนั้น เนื่องจากเราต้องทำสิ่งเดิมๆ ซ้ำกัน \(10^6\) รอบ เราสามารถใช้สิ่งที่เรียกว่า Loop ได้ ซึ่งมีอยู่ 2 ประเภทได้แก่

While Loop

While Loop เหมาะกับการใช้ในกรณีที่เราไม่รู้จำนวนรอบที่แน่นอน หรือต้องการให้หยุดตามเงื่อนไข เช่นการทำซ้ำไปเรื่อยๆ จนกว่าค่าจะเป็น 1 มีโครงสร้างดังนี้

while (condition) {
    // code ที่จะทำซ้ำ
}
  • condition คือเงื่อนไข จะเช็คทุกครั้งว่าเป็นจริงไหม ก่อนการรันโค้ดในลูป หากเป็นเท็จ จะจบการทำงานของลูป

ตัวอย่าง

ให้ \(x= 2^n\) เมื่อ \(n >= 0\) จงหาค่า \(n\) จากการรับค่า \(x\)

#include <iostream>

using namespace std;

int main() {
    int x, n = 0;
    cin >> x; // รับค่า x
    while (x > 1) { // ทำจนกว่า x จะเท่ากับ 1 ถึงหยุด
        n++; // เพิ่มค่า n
        x /= 2; // หารด้วย 2
    }
    cout << n << '\n'; // ส่งออกค่า n
}

Do While

คือ ​While Loop ที่ทำก่อน แล้วค่อยตรวจสอบ มีโครงสร้างดังนี้

do {
    // code ที่จะทำซ้ำ
} while (condition)

For Loop

For Loop เหมาะกับการใช้เมื่อเรารู้จำนวนรอบที่แน่นอนในการทำ เช่น ต้องการรับค่า \(10^6\) รอบ, ต้องการหาค่า Factorial ของจำนวนเต็ม \(x\) (คือการคูณเลขตั้งแต่ 1 ถึง \(x\)) โดยโครงสร้างของ For Loop มีดังนี้

for (initialization; condition; update) {
    // code ที่จะทำซ้ำ
}
  • initialization คือการกำหนดค่าเริ่มต้น จะถูกรัน 1 ครั้งก่อนเริ่ม
  • condition คือเงื่อนไข จะเช็คทุกครั้งว่าเป็นจริงไหม ก่อนการรันโค้ดในลูป หากเป็นเท็จ จะจบการทำงานของลูป
  • update คือคำสั่งที่ทำหลังจากจบการรันโค้ดภายในลูป มีไว้สำหรับการเปลี่ยนค่า

ตัวอย่าง

ต้องการหาค่า \(x!\) สำหรับค่า \(x\) ที่รับเข้ามา

#include <iostream>

int main() {
    int x, fac = 1;
    cin >> x // รับค่า x
    for (int i = 1; i <= x; i++) { // ลูปตั้งแต่ 1 ถึง x
        fac *= i; // คูณค่า i เข้าไปในคำตอบ
    }
    cout << fac << '\n';
}

เพิ่มเติม

  • เราสามารถใส่ Loop ซ้อนใน Loop ได้ เช่น
for (int i = 1; i <= 5; i++) {
    for (int j = 1; j <= 5; j++) cout << i * j << ' ';
    cout << '\n';
}
  • ไม่จำเป็นต้องมีปีกกาครอบโค้ด โดยจะทำงานเพียงแค่ 1 คำสั่งเท่านั้น ที่ต่อจากโค้ด (ไม่สนใจการเว้นวรรค หรือการขึ้นบรรทัดใหม่)
for (...) cout << "This is inside the loop";
cout << "This isn't inside the loop";

for (...)
    cout << "This is inside the loop";
    cout << "This isn't inside the loop";

for (...)


cout << "This is inside the loop";
cout << "This isn't inside the loop";

// โค้ดข้างต้นทั้งหมดเทียบได้กับ
// for (...) {
//     cout << "This is inside the loop";
// }
// cout << "This isn't inside the loop";

// while (...) ก็ทำงานเหมือนกับ for loop ในทำนองเดียวกัน

โจทย์แนววาดรูป (Pattern)

จงวาดรูปบันใด \(N\) ขั้นดังตัวอย่าง

N = 4
#
##
###
####
Observation

จะเห็นว่าบรรทัดที่ \(i\) จะมีเครื่องหมาย # ทั้งหมด \(i\) ตัว

Code
#include <iostream>

using namespace std;

int main() {
    int N;
    cin >> N; // รับค่า N
    for (int i = 1; i <= N; i++) { // ลูปสำหรับแต่ละแถว
        for (int j = 1; j <= i; j++) cout << '#'; // print # จำนวนเท่ากับเลขบรรทัดนั้นๆ
        cout << '\n';
    }
}

Trick

หากโจทย์มีความซับซ้อน ให้ลองมองเป็นรูปอย่างง่าย เช่น ดอกจัน โดยแบ่งเป็นช่องๆ แล้วหาความสัมพันธ์ระหว่าง \(i\) (เลขแถว) กับ \(j\) (เลขคอลัมน์)

ที่มา: ศูนย์ สอวน. โรงเรียนสามเสนวิทยาลัย - มหาวิทยาลัยธรรมศาสตร์ (ค่าย 1)

โจทย์เพิ่มเติม

Problem Source Difficulty Solution
แบบฝึกหัดคำสั่งควบคุมแบบวนซ้ำ TU1 Very Easy View
Min Max PROG Very Easy View
Okviri PROG Normal View
Great Common Divisor PROG Easy View
Skocimis PROG ? View
ดาว (star) PROG ? View
BUKA PROG ? View
กบ (frog) PROG ? View
วุ้น (jelly) PROG ? View
บินดูไฟ (skylight) PROG ? View