1

範囲が確立されており、その範囲 (10%) から一連の乱数を選択し、値が繰り返されないようにしたいと考えています。

プログラム内でこれをどのように、どこにコーディングすればよいですか?

以下、抜粋です。

// Number of Items      
int range = numberOfItems [itemNumber - 1];
// Determine 10 percent of the given range
int tenPercentOfRange = (int)(range * 0.1);
int number = 0;
int[] numbers = new int[tenPercentOfRange];

int index = 0;

for(;index < tenPercentOfRange;)
{
  // Randomly select 10% of the items for a given item.
  number = (int) (range * Math.random()) + 1;
  if(!Arrays.asList(numbers).contains(number))
  {
    numbers[index] = number;
    index++; 
    // ..................
4

3 に答える 3

2

最も簡単な方法 (最も効率的ではありませんが) は、すべての要素をリストに入力し、 を使用Collections.shuffle()して、最初の 10% の要素を選択することです。

順列には同じメインディッシュが 2 回含まれていないため (このように入力したと仮定)、最初の 10% の要素も一意になるため、適合します。

于 2012-05-12T21:47:07.277 に答える
2

collection.shuffle () を使用し、指定されたサイズのサブリストを選択するか、値をリストに入れ、インデックスの要素を削除します

found.add (list.remove (random.nextInt (list.size ())); 

X回。各ステップでリストのサイズが縮小され、要素が 2 回表示されることはありません。

ただし、非常に大きな範囲の場合、有効な long の範囲としましょう。リストを作成してシャッフルしたり値を選択したりすることは適切ではありません。

したがって、セットを作成し、ランダムな値を選択して、set.size () が必要なサイズになるまでそれらをリストに追加します。

実行可能な例:

import java.util.*;

public class Empty {

    static Random random = new Random ();

    public static void main (String args [])
    {
        show (pick (10, 100));
        show (securePick (10, 100000));
    }

    static public List <Integer> pick (int n, int max) {
        List <Integer> result = new ArrayList <Integer> ();
        List <Integer> range = new ArrayList <Integer> (max);
        for (int i= 0; i < max; ++i)
            range.add (i);
        for (int i= 0; i < n; ++i)
            result.add (range.remove (random.nextInt (range.size ()))); 
        return result;
    }

    static public Set <Integer> securePick (int n, int max) {
        Set <Integer> result = new HashSet <Integer> ();
        while (result.size () < n)
            result.add (random.nextInt (max)); 
        return result; // <Integer> 
    }

    public static void show (List <Integer> liste)
    {
        System.out.print ("[");
        for (int i : liste)
            System.out.print (i + ", ");
        System.out.println ("\b\b]");
    }

    public static void show (Set <Integer> liste)
    {
        System.out.print ("[");
        for (int i : liste)
            System.out.print (i + ", ");
        System.out.println ("\b\b]");
    }
}
于 2012-05-12T22:01:36.713 に答える
0

整数範囲の 10% のみが必要な場合は、個別の数値が得られるまで繰り返すアプローチがより効率的です。これはLinkedHashSet、重複の効率的なチェックに使用されます。

final int range = 1000, sampleSize = range / 10;
final Set<Integer> rnds = new LinkedHashSet<Integer>();
final Random r = new Random();
for (int i = 0; i < sampleSize;) if (rnds.add(r.nextInt(range) + 1)) i++;
System.out.println(rnds);
final int[] result = new int[sampleSize];
int i = 0;
for (int nr : rnds) result[i++] = nr;
于 2012-05-12T22:01:02.607 に答える