2012-04-11 61 views
7

Tôi có một phương pháp trong một lớp học như sau ...số ngẫu nhiên không quá ngẫu nhiên

class foo{ 
    int bar::randomNum10to50(){ 
     srand (time(NULL)); 
     int random10to50 = rand()%50+10; 
     return random10to50; 
    } 
} 

Tuy nhiên khi tôi gọi nó từ chính (chỉ để kiểm tra đầu ra, bởi vì tôi đã không nhận được hành vi từ chương trình mà tôi mong đợi) giống như vậy ....

chính xác cùng một số khi nó chạy (tức là 9,9,9,9,9, ....; lần chạy tiếp theo: 43, 43,43,43, .....) Tôi không biết chuyện gì đang xảy ra. Mã chạy rất nhanh vì vậy tôi đã nghĩ rằng MIGHT là vấn đề nhưng tôi không thấy tại sao sẽ không có sự khác biệt ngay cả giữa 20 lần lặp lại của nó. Bất kỳ suy nghĩ được đánh giá cao! Cảm ơn!

+0

"9,9,9,9,9" là một 'typo', phải không? Tôi chỉ tự hỏi vì bạn chỉ nên nhận được kết quả trong khoảng từ 10 đến 50 .. – jorey

Trả lời

20

Bạn cần gọi srand()sau khi, bên ngoài của chức năng ngẫu nhiên. Nếu không, bạn sẽ tái tạo trình tạo số ngẫu nhiên mỗi lần với cùng một giá trị thời gian, tạo ra cùng một giá trị "ngẫu nhiên" ban đầu.

+0

gotch ... cảm ơn! Tôi cảm thấy ngớ ngẩn. –

6

Bạn đang gọi srand() với cùng một hạt giống lặp lại mỗi vòng lặp, vì thời gian không thực sự có, um, thời gian để thay đổi. Hãy chắc chắn để gọi nó chỉ một lần và mọi thứ sẽ hoạt động.

3

Cody Grey đã nói những gì bạn đang làm sai ở đây, nhưng đây là một ví dụ để làm điều này với <random> thư viện:

#include <random> 

std::mt19937 make_seeded_engine() { 
    std::random_device r; 
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; 
    return std::mt19937(seed); 
} 

class foo { 
    std::mt19937 engine; 

public: 
    foo() : engine(make_seeded_engine()) {} 

    int randomNum10to50(){ 
     return std::uniform_int_distribution<>(10,50)(engine); 
    } 
}; 

foo create; 
for (int i=0; i<20;i++){ 
    cout << create.randomNum10to50() << '\n'; 
} 

Lưu ý rằng rand()%50 + 10 sản xuất số trong phạm vi từ 10 đến 59, không phải 10 đến 50. uniform_int_distribution là tốt hơn bởi vì phạm vi bạn cung cấp cho nó là phạm vi bạn nhận được, vì vậy bạn ít có khả năng mess nó lên. Cũng sử dụng uniform_int_distribution cho bạn kết quả không thiên vị trong khi rand()%50+10 có một số sai lệch nhỏ.


Nếu bạn có một trình biên dịch với một chút hơn C++ 11 hỗ trợ bạn có thể làm:

class foo{ 
    std::mt19937 engine = make_seeded_engine(); 

public: 
    int randomNum10to50(){ 
     return std::uniform_int_distribution<>(10,50)(engine); 
    } 
}; 
+0

đẹp! Cảm ơn! Tôi có thể sẽ sử dụng nó. Thông tin tốt! –

+0

Lưu ý trình biên dịch của bạn sẽ cần phải hỗ trợ C++ 11 để làm điều này nếu không bạn có thể sử dụng boost đó là nơi '' xuất phát từ tôi tin. – AJG85

+0

@ AJG85 Vâng, nó sử dụng một số C++ 11, nhưng tôi đã cẩn thận để giới hạn nó cho những gì được hỗ trợ rộng rãi. VS11 và gcc ở mức 4.5 trở lại có thể chạy được. Nhưng tôi nghĩ rằng tôi sẽ thêm một phiên bản sử dụng nhiều C++ 11 để làm sạch nó một chút ... – bames53