2013-02-18 36 views
6

Tôi muốn tạo các số ngẫu nhiên, nhưng không muốn các số này nằm trong dãy từ excludeRows. Đây là mã của tôi.Tạo các số ngẫu nhiên ngoại trừ các giá trị nhất định

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) { 
    Random rand = new Random(); 
    int range = end - start +1 - excludeRows.size(); 
    int random = rand.nextInt(range) + 1; 

    for(int i = 0; i < exclude.size(); i++) { 
     if(excludeRows.get(i) > random) { 
      return random; 
     } 
     random++; 
    } 

    return random; 
} 

Tôi sử dụng hàm này trong một vòng lặp while và trong mỗi lần lặp tôi thêm một giá trị mới vào excludeRows. Đôi khi nó trả về các số thuộc về excludeRows. Có chuyện gì vậy?

+2

'Loại trừ' và' loại trừ' giống nhau không? – Vlad

+0

có, tôi quên đổi tên – user2081119

+0

Trong chức năng này, bạn không thêm số vào 'excludeRows'. Vì vậy, trong giải pháp của tôi, tôi không làm điều đó. Tôi có nên bổ sung nó không? – qben

Trả lời

5
if(!exclude.contains(random)) 
    return random; 

Hãy thử điều này mỗi khi nó sẽ trả lại giá trị không có trong loại trừ.

+1

nó hoạt động! Cảm ơn rất nhiều! :) – user2081119

+0

@ user2081119 Bạn có thể upvote và chấp nhận. Cảm ơn –

+0

@ user2081119 Tôi đề nghị bạn hãy xem giải pháp của tôi. Có một số nhận xét đó sẽ là hữu ích tôi nghĩ. – qben

2

Bạn kiểm tra:

for(int i = 0; i < exclude.size(); i++) { 
    if(exclude.get(i) > random) { 
     return random; 
    } 

và nếu chỉ là người đầu tiên là lớn hơn, bạn sẽ trả về giá trị. Bạn có chắc chắn exclude được sắp xếp không?

Bạn có thể sử dụng if(exclude.contains(random)) hoặc các thuật toán sau đây:

nếu (end-start) là một số lượng hợp lý, và bạn cần phải gần như tất cả các giá trị mà bạn có thể tạo một danh sách tất cả các số có thể chấp nhận và sử dụng ngẫu nhiên trên kích thước danh sách này và chọn ngẫu nhiên giá trị làm chỉ mục. sau đó xóa số không mong muốn khỏi danh sách và nhận một chỉ mục ngẫu nhiên khác.

+2

Tôi tin rằng ông dựa vào thực tế là loại trừ được sắp xếp. –

6

Tôi nghĩ có một số sai lầm.

1) Phạm vi phải kết thúc - bắt đầu + 1, vì đây là phạm vi mong muốn.
2) Nếu bạn thực sự muốn các số ngẫu nhiên (như "ngẫu nhiên" càng tốt trên máy tính) thì bạn không nên chỉ nhận số tiếp theo. Bởi vì trong trường hợp này, số ngẫu nhiên của bạn sẽ có các đặc tính của mật độ/tần số được loại trừ.

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) { 
    Random rand = new Random(); 
    int range = end - start + 1; 
    int random; 

    boolean success = false; 
    while(!success) { 
     random = rand.nextInt(range) + 1; 
     for(Integer i: excludeRows) { 
      if(i == random) { 
       break; 
      } else if (i > random) { 
       success = true; 
       break; 
      } 
     } 
    } 
    return random; 
} 

CẬP NHẬT

Với câu trả lời Achintya Jha của mã của tôi có thể được cải thiện (nhưng lưu ý có một số nhận xét cũng):

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) { 
    Random rand = new Random(); 
    int range = end - start + 1; 

    int random = rand.nextInt(range) + 1; 
    while(excludeRows.contains(random)) { 
     random = rand.nextInt(range) + 1; 
    } 

    return random; 
} 
+1

Cảm ơn rất nhiều! giải pháp tốt đẹp – user2081119

0

Thực ra, chúng tôi không cần sử dụng contains(random) với vòng lặp while.

Để đơn giản hóa câu hỏi, hãy xem điều gì sẽ xảy ra nếu chúng tôi chỉ có một loại trừ giá trị. Chúng tôi có thể chia kết quả thành các phần 2. Sau đó, số lượng giá trị có thể là range-1. Nếu số ngẫu nhiên nhỏ hơn giá trị bị loại trừ, chỉ cần trả lại số đó. Nếu không, chúng tôi có thể thêm 1.

Đối với nhiều loại trừ giá trị, Chúng tôi có thể chia bộ kết quả thành các phần size+1, trong đó size là số lượng giá trị loại trừ. Sau đó, số lượng giá trị có thể là range-size. Sau đó, chúng tôi sắp xếp loại trừ giá trị theo thứ tự tăng dần. Nếu số ngẫu nhiên nhỏ hơn giá trị loại trừ trừ i, thì chúng tôi chỉ trả lại số ngẫu nhiên thêm i, trong đó i là chỉ mục của giá trị loại trừ.

public int generateRandomNumberWithExcepts(int start, int end, List<Integer> excepts) { 
    int size = excepts.size(); 
    int range = end - start + 1 - size; 
    int randNum = random.nextInt(range) + start; 
    excepts.sort(null); // sort excluding values in ascending order 
    int i=0; 
    for(int except : excepts) { 
     if(randNum < except-i){ 
      return randNum + i; 
     } 
     i++; 
    } 
    return randNum + i; 
} 
Các vấn đề liên quan