2010-08-03 2 views
1

Вот как я генерирую уникальное значение между 1 и 6 и получаю соответствующие изображения из выпадающей папки.Как получить уникальное случайное число?

Random rand = new Random(); 
// n = the number of images, that start at idx 1 
rndInt = rand.nextInt(6) + 1; 
String imgName = "card" + rndInt; 
int id = getResources().getIdentifier(imgName, "drawable", getPackageName()); 
imgView.setImageResource(id); 

Что я хочу, я должен вызвать этот метод в 7 раз, и каждый раз, когда этот метод должен возвращать уникальный случайные Нет. так что ни один из уже выбранных номеров не появится снова.

+1

Если есть только 6 возможных значений, как вы собираетесь получить 7 уникальных номеров? –

+10

«Уникальные» и «Случайные» являются взаимоисключающими. У вас не может быть обоих. –

+0

@ Dan dyer sry my bad. я изменил его на 7. @greg D .. чувак, плз с принятым символом ... этот код создает уникальный и выкуп нет. – iscavengers

ответ

37

Обычный подход к этой проблеме состоит в том, чтобы создать список, содержащий все возможные значения, и перетасовать его (используйте Collections.shuffle). Затем вы потребляете один элемент из списка каждый раз, когда вам нужно значение. Это гарантирует, что вы не используете одно и то же значение более одного раза, но все же допускаете случайный порядок.

+0

Похоже, вы используете это для перетасовки карт. Разве было бы лучше не загружать все карты, а затем перетасовывать их? Подход подобен этому ответу. –

+3

+1 Гораздо лучше, чем принятый ответ. Интересно, был ли ваш прием принят, если у него был код. – MAK

-4

Создайте статический список возможностей, которые вы уже получили.

static ArrayList<int> listIdontWantAnymore = new ArrayList<int>(); 

int NextRandomNumber() { 
    Random random = new Random(); 
    int myRandomInt; 

    do { 
     myRandomInt = random.NextInt(6) + 1; 
    } while(listIdontWantAnymore.Contains(myRandomInt)); 

    listIdontWantAnymore.Add(myRandomInt); 

    // now your 'myRandomInt' is what you want it to be. 
    return myRandomInt; 
} 
+4

Я думаю, что любое решение вроде этого должно иметь отказоустойчивую систему, чтобы избежать неприятных тупиков. Это может закончиться плохо;) – monoceres

+0

Это было идеально, человек .. dat wat i waz looking for, теперь я могу создать уникальное случайное число спасибо большое. – iscavengers

+6

@ shishir.bobby: нет, это было не идеально. Это было ужасно. Пожалуйста, не используйте это «решение». –

8

Вот пример класса, который создает случайную перестановку, используя подход, предложенный Дэном Дайером. Он гарантирует, что каждый вызов .next() дает новое число до номера, указанного в конструкторе. После этого он обертывается и снова возвращает ту же последовательность. Это может быть полезно для перетасовки списка воспроизведения.

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class RandomPermutation{ 
    private List<Integer> list; 
    private int index; 

    /** 
    * Create a random permutation the sequence of numbers 0, 1, ... , n - 1. 
    * @param n Range specifier, must be positive 
    */ 
    public RandomPermutation(int n) { 
     if (n <= 1) { 
      throw new IllegalArgumentException(
        "Positive number expected, got: " + n); 
     } 
     list = new ArrayList<Integer>(); 
     newList(n); 
    } 

    /** 
    * Creates a new list 
    */ 
    public void newList(int n) { 
     index = -1; 
     list.clear(); 
     for (int i = 0; i < n; i++) { 
      list.add(i); 
     } 
     Collections.shuffle(list); 
    } 

    /** 
    * Retrieve the next integer in sequence. 
    */ 
    public int next() { 
     index = (index + 1) % list.size(); 
     return list.get(index); 
    } 
} 

КПП. не используйте подход, используемый Снейком. Не только потому, что он замерзнет, ​​как только все числа будут использованы. Это можно исправить. Проблема в том, что процедура выполняется медленнее и медленнее, поскольку все больше и больше номеров находятся в списке IdontWantAnymore. С 6 номерами это не проблема, но это может привести к значительному замедлению, если диапазон большой. Рассмотрим выбор между 10000 номерами. После того, как было выбрано 9900 номеров, есть шанс 1% получить хороший номер. после 9990 номеров есть 0,1% шанс поразить хороший номер и т.д.

Вот пример того, как можно использовать класс:

static RandomPermutation randomPerm = new RandomPermutation(7) 

int NextRandomNumber() { 
    return randomPerm.next() + 1; 
} 
+0

спасибо zeriab, я реализовал подход ура и его работу f9. может у plz сказать мне еще одну вещь, нравится u должен hv видел таймер, таймер обратного отсчета, показывающий значения от 10 до 0, видимые на виду. Как я могу показать случайное число, меняется на мой взгляд. Еще раз спасибо mate – iscavengers

1

Для конкретной потребительной случае, это следует делать Хитрость.

Random rand = new Random(); 
// n = the number of images 
List<String> imgNames = new ArrayList<String>(n); 
for (int i = 0; i < n; i++) { 
    imgNames.add("card" + (i + 1)) 
} 
while (!imageNames.isEmpty()) { 
    String imgName = imgNames.remove(rand.next(imageNames.size()); 
    int id = getResources().getIdentifier(imgName, "drawable", getPackageName()); 
    imgView.setImageResource(id); 
} 

Учтите, что это не очень хорошо масштабируется, как n становится большим. Операция удаления - O(n) для ArrayList или LinkedList. Но для n в сотнях или тысячах это, вероятно, незначительно по сравнению с загрузкой и отображением изображений.

Кроме того, поскольку в комментариях отмечается «уникальные случайные числа», это противоречие в терминах. Зачем вам стоит случайная перестановка набора чисел от 1 до n. Мое решение дает вам это без явного шага «перетасовки», и этого достаточно для вашего прецедента.

+0

Я бы сказал, что совершенно ясно, что «уникальные случайные числа» означают, что один и тот же образец не следует выбирать более одного раза. На боковой ноте: операция removeFirst() в LinkedList - это O (1). – Zeriab

+0

@Zeriab - * "Операция removeFirst() в LinkedList - это O (1)" *. Как это важно? Алгоритм не использует этот метод. –

+0

@ Zeriab - «уникальное случайное число» может быть вам понятен, но это абсурд с математической точки зрения. Подобно тому, как говорить о наборах, которые допускают дубликаты. –

1

Создайте список номеров, содержащих все числа, которые вы будете использовать. (Что хорошо, учитывая, что мы говорим о небольшом диапазоне, где «N» «где-то меньше тысячи»)

Когда вы выберете номер, выберите случайный индекс между 0 и sizeof (список) это число становится индексом этого списка.

Удалите этот список и верните номер.

(Это упражнение для читателя, чтобы определить, какой из «списка» здесь уместно.)

2

Вот самый простой код, чтобы сделать это, и хранить в массиве без повторения:

Random rand = new Random(); 
int[] ar; 
ar = new int[5]; 

int random = 0; 
int [] result_arr=new int[5]; 
boolean flag=false; 

for(int i=0;i<5;i++) 
{ 
    ar[i]=0; 

    do{ 
     random =rand.nextInt(10); 
     flag=false; 
     for(int j=0;j<i;j++) 
     { 
      if(ar[j]==random) 
      flag=true; 
     } 
     if(!flag) 
     { 
      ar[i]=random; 
      break; 
     } 
    } 
    while(true) ; 
} 

это создаст уникальные номера в массиве

Смежные вопросы