Tại sao điều này đôi khi trả về 2?Trả về Số ngẫu nhiên nhưng không phải 2
function pickServer(){
$varr = rand(1,4);
if($varr==2){
pickServer();
}
return $varr;
}
Tại sao điều này đôi khi trả về 2?Trả về Số ngẫu nhiên nhưng không phải 2
function pickServer(){
$varr = rand(1,4);
if($varr==2){
pickServer();
}
return $varr;
}
Vì bạn không dừng chức năng ở đó. dòng thứ tư nên đọc:
return pickServer();
Điều này vẫn còn đệ quy và có khả năng gây nguy hiểm. Xem phần thảo luận nhận xét về câu hỏi gốc. –
Điều này hữu ích khi trả lời "tại sao". Nhưng nó kết quả trong một giải pháp đáng sợ, như Robert chỉ ra. – Nosredna
Bởi vì khi giá trị là 2 bạn không trả lại máy chủ. Và hàm tiếp tục trả về $ varr.
Nó gọi hàm đệ quy để lấy số khác không phải là 2, nhưng không làm gì với kết quả đó.
Hãy thử thay đổi pickServer() đến return selectServer().
Vẫn còn tốt hơn, hãy viết các chức năng lặp đi lặp lại để nó chỉ vòng cho đến khi giá trị trả về không phải là 2.
function pickServer(){
$varr = rand(1,4);
if($varr==2){
return pickServer(); //leave here
}
return $varr;
}
Những gì bạn có thể muốn là
function pickServer(){
$varr = rand(1,4);
if($varr==2){
$varr = pickServer();
}
return $varr;
}
- nhưng lưu ý rằng có không đảm bảo rằng điều này không đi vào một quá trình đệ quy quá dài. Có lẽ bạn thay vì phải làm một cái gì đó như thế này:
function pickServer(){
$varr = rand(1,3);
if($varr > 1){
$varr = $varr + 1;
}
return $varr;
}
Hoạt động cũng như tác phẩm của Nosredna, nhưng phải suy nghĩ một giây. – OIS
Đoạn mã thứ hai của bạn giải quyết tốt vấn đề này. Mối quan tâm của tôi với nó chỉ là một chút khó khăn để giải mã. Trong thực tế, tôi đã bỏ lỡ nó khi tôi đọc câu trả lời lần đầu tiên thông qua chính xác bởi vì nó không rõ ràng. Tôi xin lỗi vì đã bỏ lỡ nó. Tôi có để ý đến thời gian nắm tay không, tôi đã ghi nhận bạn trong câu trả lời của tôi. – Nosredna
Cập nhật: Tôi cung cấp cho bạn các đạo cụ trong câu trả lời của tôi. – Nosredna
Bạn quên trả về giá trị ...
function pickServer(){
$varr = rand(1,4);
if($varr==2){
return pickServer();
}
return $varr;
}
Một cách khác để làm điều đó là sử dụng do … while
:
function pickServer() {
do {
$varr = rand(1,4);
} while ($varr == 2);
return $varr;
}
Có thể cho rằng tốt hơn vì hầu hết các ngôn ngữ không tối ưu hóa tính năng đệ quy đuôi và điều này không kém rõ ràng so với việc đệ quy. –
Cuối cùng một người nào đó với một số ý nghĩa để chỉ ra rằng bằng cách sử dụng đệ quy như một goto là điên. +1 – JohnFx
Tôi nghĩ rằng vấn đề ở tầm tay, cả đệ quy và vòng lặp đều điên rồ. :-) – Nosredna
Câu trả lời cho câu hỏi của bạn, như những người khác đã chỉ ra, là mã của bạn rơi qua mà không quay trở lại. Nếu 2
được trả về bởi lệnh gọi rand() trên cả lần thử đầu tiên và lần thử thứ hai (có 1/16 cơ hội xảy ra này), bạn sẽ nhận được kết quả là 2
.
Nhưng cách tiếp cận của bạn để giải quyết vấn đề có thể tốt hơn.
Cả đệ quy và vòng lặp đều mang tính chiến đấu cho vấn đề này. Đây là vấn đề về bản đồ , không phải là sự cố ngẫu nhiên . (Nó giống như một số ngẫu nhiên thông thường mã hóa các vấn đề cuộc phỏng vấn có thể được xử lý một cách dễ dàng nhất trong một vòng lặp từ chối, nhưng nó thực sự không phải là một vấn đề của lớp đó.)
Bạn muốn một trong ba kết quả, không Bốn . (1, 3, và 4.) Điều đó có nghĩa là bạn nên tạo ra một loạt ba số ngẫu nhiên, không phải là bốn. Bạn có thể remap với một mảng hoặc sử dụng một if
. Cả hai khả năng được hiển thị dưới đây. Hãy cho tôi biết nếu tôi có cú pháp sai - PHPfu của tôi là yếu sáng nay.
/* array remapping */
function pickServer() {
$remap = array(1, 3, 4);
return $remap[rand(1,3)];
}
/* if remapping */
function pickServer() {
$server = rand(1,3);
if ($server==2) {
$server=4;
}
return $server;
}
Tôi không nhận thấy điều đó trước đây, nhưng balpha đã đoán trước câu trả lời của tôi. Ông đã remapped với một số if
trong ví dụ thứ hai của mình. Thay vì remapping 2 đến 4, anh ta chỉ thêm một vào bất kỳ câu trả lời nào ở trên 1, là một giải pháp tương đương.
Cú pháp có vẻ đúng với tôi. Làm tốt. * Điều này * đáng lẽ phải là câu trả lời đã chọn. –
RNG ngẫu nhiên thực sự có thể trả về 2 mãi mãi. Ít nhất điều này sẽ không bị mắc kẹt trong một vòng lặp. – OIS
Tôi nghĩ bạn sẽ thấy RNG thực sự luôn trả về 4: http://imgs.xkcd.com/comics/random_number.png – nickf
tôi sẽ để một cái gì đó như thế này:
function pickServer()
{
$servers = array(1,3,4);
return $servers[rand(1,count($servers))];
}
Bạn có thể loại bỏ các đệ quy và remap một lựa chọn ngẫu nhiên 2. Đơn giản chỉ cần giảm phạm vi và bản đồ đầu của dãy núi này (trong trường hợp này 2) 1.
function pickServer(){
$varr = rand(2,4);
if($varr==2){
return 1;
}
return $varr;
}
Cảm ơn tất cả mọi người, tất cả đều đúng, nhưng tôi phải chọn một. :) – Abs
Trên thực tế hầu hết trong số họ đang thiếu các vấn đề thực sự (bao gồm cả câu trả lời được chấp nhận). Không sử dụng đệ quy như một Goto. Đặt vòng lặp quanh lệnh $ var = rand (1,4) cho đến khi nó trả về một giá trị! = 2, không gọi lại máy chủ pickServer bên trong phương thức này. Hãy nghĩ về những đứa trẻ! Hãy nghĩ về Frame Stack của bạn! Nếu bạn chạy mã này và nhấn một vệt 2 bạn có thể tạo ra các điều kiện StackOverflow về mặt lý thuyết và tôi không nói về một trang Wiki Q & A. – JohnFx
Đừng lặp lại. Phạm vi tạo ngẫu nhiên của bạn quá lớn - bạn không thấy nó vì số bạn muốn loại trừ nằm trong phạm vi. Nếu nó đã ở đầu hoặc cuối bạn sẽ không lặp lại, vậy tại sao vòng lặp chỉ vì nó ở giữa? Remap. – Nosredna