การสุ่มตัวเลข ในภาษา C และ C++

ในบทความนี้ คุณจะได้เรียนรู้เกี่ยวกับการเขียนโปรแกรมเพื่อสุ่มตัวเลขในภาษา C และภาษา C++ เราจะเขียนโค้ดเพื่อสุ่มตัวเลขโดยการใช้ฟังก์ชัน rand จากไลบรารี่ stdlib.h (หรือ cstdlib ในภาษา C++) และในตอนท้ายของบท จะเป็นการสร้างฟังก์ชันเพื่อสุ่มตัวเลขระหว่างช่วงที่กำหนด

ฟังก์ชันสุ่มตัวเลข rand

เราสามารถใช้ฟังก์ชัน rand เพื่อสุ่มตัวเลขในภาษา C หรือภาษา C++ ได้ ฟังก์ชันนี้เป็นฟังก์ชันจากไลบรารี่มาตรฐาน stdlib.h นี่เป็นรูปแบบการใช้งาน

int rand(void);

ฟังก์ชันไม่มีพารามิเตอร์ เมื่อเราเรียกใช้งานมันจะสุ่มส่งค่ากลับเป็นตัวเลขจำนวนเต็มระหว่าง 0 - RAND_MAX โดยที่ RAND_MAX นั้นเป็นค่าคงที่ที่แตกต่างกันในแต่ละแพลตฟอร์ม โดยทั่วไปแล้วจะมีอยู่ค่าที่ 32767 ซึ่งเป็นข้อมูลประเภท short ต่อไปมาดูโค้ดตัวอย่างการสุ่มตัวเลขในภาษา C และภาษา C++

random.c
#include <stdio.h>
#include <stdlib.h>

int main()
{
    for (int i = 0; i < 5; i++) {
        printf("%d ", rand());
    }
    return 0;
}
random.cpp
#include <iostream>
#include <cstdlib>

int main()
{
    for (int i = 0; i < 5; i++) {
        std::cout << rand() << " ";
    }
    return 0;
}

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

41 18467 6334 26500 19169

ในตัวอย่าง เป็นโค้ดสำหรับการสุ่มตัวเลขในภาษา C และภาษา C++ อย่างที่คุณเห็น สิ่งที่แตกต่างกันระหว่างของทั้งสองภาษาก็คือ ในภาษา C++ เราได้ทำการนำเข้าไลบรารี่จากไฟล์ cstdlib แทน หลังจากนั้นเรียกใช้ฟังก์ชัน rand เพื่อสุ่มตัวเลขเป็นจำนวน 5 ตัวเลขและแสดงผลออกทางหน้าจอ

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

การสุ่มตัวเลขแบบไม่ซ้ำด้วยฟังก์ชัน srand

เพื่อทำให้การสุ่มตัวเลขนั้นแตกต่างกันออกไปในการรันแต่ละครั้ง เราจำเป็นต้องสร้าง random seed เพื่อให้ฟังก์ชัน rand นำค่าดังกล่าวไปใช้ในการสุ่มตัวเลข ซึ่งค่า random seed นั้นควรจะสร้างมาจากค่าที่ไม่สามารถคาดเดาได้ ยกตัวอย่าง ค่าของเวลาปัจจุบัน ดังนั้นเมื่อสร้าง random seed ได้แล้ว เราสามารถตั้งค่ามันด้วยฟังก์ชัน srand

random_seed.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    srand(time(NULL));

    for (int i = 0; i < 5; i++) {
        printf("%d ", rand());
    }
    return 0;
}
random_seed.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>

int main()
{
    srand(time(NULL));

    for (int i = 0; i < 5; i++) {
        std::cout << rand() << " ";
    }
    return 0;
}

นี่เป็นผลลัพธ์การทำงานของโปรแกรมเมื่อเรารันโปรแกรมสามครั้ง

10680 25517 30576 2481 29439
10739 22380 24451 9637 18493
10791 30515 15366 1434 19687

ในตอนนี้ เราได้อัพเดทโค้ดจากในตัวอย่างก่อนหน้าของเรา เพื่อให้การสุ่มตัวเลขไม่ซ้ำกันในการรันแต่ละครั้ง โดยการใช้ฟังก์ชัน srand เข้ามาช่วยในการกำหนดค่า random seed ให้กับโปรแกรม

srand(time(NULL));

ฟังก์ชัน srand ใช้กำหนด random seed ให้กับการทำงานของฟังก์ชัน rand ในกรณีนี้ เราสร้าง rand seed ด้วยการเรียกใช้งานฟังก์ชัน time(NULL) เพื่อรับเอาค่าเวลาปัจจุบันมาทำเป็นค่าของ random seed เนื่องจากเวลานั้นจะเปลี่ยนแปลงไปในการรันโปรแกรมแต่ละครั้ง ดังนั้นจึงทำให้ตัวเลขที่สุ่มออกมาไม่ซ้ำกันนั่นเอง

การสุ่มตัวเลขระหว่าง 1 - 100

อย่างที่เราได้บอกไปว่าฟังก์ชัน rand นั้นจะสุ่มตัวเลขที่มีค่าระหว่าง 0 - RAND_MAX ซึ่งในการเขียนโปรแกรมจริงๆ แล้วเราอาจจะต้องการสุ่มตัวเลขที่มีค่าอยู่ในช่วงที่กำหนด เช่น 1 - 10 หรือ 1 - 100 เป็นต้น ต่อไปมาดูตัวอย่างสำหรับการสุ่มตัวเลขตามช่วงที่กำหนด

random_between.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int random_between(int min, int max)
{
    int r = (rand() / (float) RAND_MAX) * (max + 1) + min;
    return r > max ? max: r;
}

int main()
{
    srand(time(NULL));

    printf("Random between 1 to 10\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", random_between(1, 10));
    }

    printf("\nRandom between 1 to 100\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", random_between(1, 100));
    }
    return 0;
}
random_between.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int random_between(int min, int max)
{
    int r = (rand() / (float) RAND_MAX) * (max + 1) + min;
    return r > max ? max: r;
}

int main()
{
    srand(time(NULL));

    cout << "Random between 1 to 10" << endl;
    for (int i = 0; i < 10; i++) {
        cout << random_between(1, 10) << " ";
    }

    cout << "\nRandom between 1 to 100" << endl;
    for (int i = 0; i < 10; i++) {
        cout << random_between(1, 100) << " ";
    }
    return 0;
}

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Random between 1 to 10
7 10 9 6 1 10 1 3 7 6
Random between 1 to 100
7 56 96 22 49 73 57 86 63 83

ในตัวอย่าง เราได้สร้างฟังก์ชัน random_between สำหรับสุ่มตัวเลขระหว่าง min และ max อย่างไรก็ตาม ฟังก์ชันนี้สามารถทำงานได้กับจำนวนเต็มที่มากกว่าหรือเท่ากับศูนย์เท่านั้น เราใช้ฟังก์ชันเพื่อสุ่มตัวเลขจาก 1 - 10 และ 1 - 100 และแสดงผลออกทางหน้าจอตามลำดับ

int random_between(int min, int max)
{
    int r = (rand() / (float) RAND_MAX) * (max + 1) + min;
    return r > max ? max: r;
}

นี่เป็นฟังก์ชันสุ่มตัวเลขระหว่าง min และ max สำหรับการทำงานของฟังก์ชันนั้น เราสร้างตัวเลขหลังจากที่สุ่มมาได้จากฟังก์ชัน rand ให้มีค่าอยู่ระหว่าง 0.0 - 1.0 โดยการนำค่าไปหารด้วยตัวเลขสูงที่สุดที่ฟังก์ชันจะสามารถสุ่มได้ ด้วยนิพจน์

rand() / (float) RAND_MAX;

หลังจากนั้นเรานำค่าที่ได้คูณกับ max + 1 เพื่อขยายขนาดของตัวเลขให้มากสุดเท่ากับค่าของ max และกรณีที่ค่าของ min มากกว่าศูนย์ เราทำการเลื่อนตัวเลขให้ไปเริ่มต้นที่ min โดยการบวกค่านี้เข้าไป

โปรแกรมสุ่มตัวเลข และสุ่มสิ่งของ

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

ดังนั้นในตัวอย่างนี้ เราจะเขียนโปรแกรมที่ทำงานคล้ายกัน มันเป็นโปรแกรมสำหรับสุ่มผลไม้ที่คุณจะได้รับจากการเข้าร่วมเล่นเกมของเรา นี่เป็นโค้ดของโปรแกรม

random_item.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int random_between(int min, int max)
{
    int r = (rand() / (float) RAND_MAX) * (max + 1) + min;
    return r > max ? max: r;
}

int main()
{
    srand(time(NULL));

    char fruits[][15] = {
        "Tomatoe(s)",
        "Banana(s)",
        "Watermelon(s)",
        "Apple(s)",
        "Grapefruit"
    };

    int amount = random_between(1, 10);
    int index = random_between(0, 4);

    printf("You received %d %s", amount, fruits[index]);
    return 0;
}
random_item.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>

int random_between(int min, int max)
{
    int r = (rand() / (float) RAND_MAX) * (max + 1) + min;
    return r > max ? max: r;
}

int main()
{
    srand(time(NULL));

    std::string fruits[] = {
        "Tomatoe(s)",
        "Banana(s)",
        "Watermelon(s)",
        "Apple(s)",
        "Grapefruit"
    };

    int amount = random_between(1, 10);
    int index = random_between(0, 4);

    std::cout << "You received " << amount << " " << fruits[index];
    return 0;
}

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

You received 9 Tomatoe(s)

ในตัวอย่าง เป็นโปรแกรมสุ่มว่าเราจะได้รับผลไม้อะไร และได้รับเป็นจำนวนเท่าไหร่ เราได้ใช้ฟังก์ชัน random_between ที่เราได้สร้างไปก่อนในตัวอย่างก่อนหน้า เพื่อนำมาสุ่มตัวเลขตามช่วงที่กำหนด

int amount = random_between(1, 10);

ในบรรทัดนี้ เราได้สุ่มจำนวนของผลไม้ที่คุณจะได้รับเมื่อรันโปรแกรม โดยค่าผลไม้ที่คุณจะได้นั้นสามารถเป็นได้ตั้งแต่ 1 - 10 ขึ้นอยู่กับว่าคุณโชคดีแค่ไหน

char fruits[][15] = {
    "Tomatoe(s)",
    "Banana(s)",
    "Watermelon(s)",
    "Apple(s)",
    "Grapefruit"
};

...

int index = random_between(0, 4);

เรามีอาเรย์ fruits สำหรับเก็บชื่อของผลไม้จำนวน 5 ชนิดที่เป็นไปได้ในการสุ่ม ดังนั้นเพื่อเข้าถึงค่าในอาเรย์ เราได้สุ่มเอาค่า Index ของอาเรย์ที่มีค่าระหว่าง 0 - 4 หลังจากนั้นเราแสดงผลลัพธ์การสุ่มออกทางหน้าจอ

ในบทความนี้ คุณได้เรียนรู้เกี่ยวกับการสุ่มตัวเลขในภาษา C และ C++ โดยการใช้ฟังก์ชัน rand และการทำให้ตัวเลขที่สุ่มออกมาในการรันแต่ละครั้งไม่เหมือนกันด้วยฟังก์ชัน srand เราใช้ฟังก์ชัน time เพื่อสร้าง random seed จากค่าของเวลาปัจจุบัน และสุดท้ายคุณได้เห็นตัวอย่างการเขียนโปรแกรมที่ประยุกต์ใช้การสุ่มตัวเลข