Генерация уникального набора случайных целых чисел - PullRequest
3 голосов
/ 15 февраля 2012

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

Это мой код между прочим:

    package rando.mizer;

    import java.util.Random;

    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;

    public class RandomizerFinalActivity extends Activity {
        /** Called when the activity is first created. */   
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Button buttonGenerate = (Button)findViewById(R.id.button1);
            final EditText aantalT= (EditText)findViewById(R.id.editText1);
            final EditText laagsteT = (EditText)findViewById(R.id.editText2);
            final EditText hoogsteT = (EditText)findViewById(R.id.editText3);
            final EditText uitvoerT = (EditText)findViewById(R.id.editText4); 



            buttonGenerate.setOnClickListener(new Button.OnClickListener(){

               public void onClick(View arg0) {
                    final int aantal = Integer.parseInt(aantalT.getText().toString());
                    final int laagste = Integer.parseInt(laagsteT.getText().toString());
                    final int hoogste = Integer.parseInt(hoogsteT.getText().toString());

                    uitvoerT.setText("");
                    Random r = new Random();

                    int aNumber;
                    String build = "";


                for(int i = 0; i < aantal; i++) {
                    aNumber = laagste + r.nextInt(hoogste + 1 - laagste);
                    build += aNumber + ",\n";
                }

                    uitvoerT.setText(build);


              }

            });
        }
    }

Ответы [ 5 ]

1 голос
/ 15 февраля 2012

Использование Collections.shuffle - отличная идея, но вам не нужно перемешивать все числа.Было бы более эффективно использовать:

// return nNumbers distinct values from low to (high - 1)
public List<Integer> getRandoms(int low, int high, int nNumbers) {
    int range = high - low;
    List<Integer> workArray = new ArrayList(range);
    for (Integer i = low; i < high; i++)
        workArray.add(i);

    // Put the chosen values at the start of the array one by one 
    // (and then do not touch the start of the array).
    int pseudoStartIndex = 0;
    while (pseudoStartIndex < nNumbers) {
        int randomIndex = pseudoStartIndex + 
                          random.nextInt(range - pseudoStartIndex); 
        Integer tempSwap = workArray.get(pseudoStartIndex);
        workArray.set(pseudoStartIndex, workArray.get(randomIndex));
        workArray.set(randomIndex, tempSwap);
        pseudoStartIndex++;
    }
    return workArray.subList(0, nNumbers);
}

Это в основном случай Фишера-Йейтса , но применяется только к нескольким элементам.

0 голосов
/ 15 февраля 2012

Было бы гораздо лучше, если бы вы однажды создали и инициализировали (он с помощью начального числа) объект Random, вместо того, чтобы создавать случайные при каждом вызове вашего слушателя, было бы менее вероятно иметь дублирующиеся числа.

0 голосов
/ 15 февраля 2012

Ваша проблема здесь в том, что вы используете всегда одно и то же начальное число, поэтому шансы на генерацию одного и того же числа очень велики. Прежде всего вы должны понять, что невозможно сгенерировать чисто случайное число, что дает вам Java. достойный механизм, но опирается на семя.

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

new Random(System.currentTimeMillis())

Вы обнаружите, что вы не получаете дубликаты. Вы можете попробовать это с этим кодом:

public static void main (String... args){
   for (int i=0; i<10000; i++){
       try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
       Random random = new Random(System.currentTimeMillis());
       System.out.println(random.nextInt());

   }
}
0 голосов
/ 15 февраля 2012

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

/** Will pick `count` numbers randomly from the set of numbers between
 * startNumber (included) and endNumber (excluded). */
public static Collection<Integer> randomPick(int startNumber, int endNumber, int count) {
    // Generate a list of all numbers from start to endNumber
    List<Integer> numbers = new ArrayList<Integer>();
    for(int i = startNumber; i < endNumber; i++) {
        numbers.add(i);
    }

    // Shuffle them
    Collections.shuffle(numbers);

    // Pick count items.
    return numbers.subList(0, count);
}
0 голосов
/ 15 февраля 2012
import java.util.Set;

Set<Integer> mySet = new HashSet<Integer>(10); // do you know how many elements do you need?
boolean elementNotThere;
do {
    int myInt = r.nextInt(hoogste + 1 - laagste);
    elementNotThere = mySet.add(myInt);
} while ( ! elementNotThere );
...