Случайно пропустить 'X' процент слов из Java Iterator

1

У меня есть код java:

   String line = value.toString();
   StringTokenizer tokenizer = new StringTokenizer(line);

   while (tokenizer.hasMoreTokens()) {
         // do someything   
   }

Тем не менее, я хочу, чтобы код случайно пропускал X процентов токенов.

Пример: если маркеры [a, b, c, d] и процент пропусков составляют 50%, то действительное выполнение может печатать любые два токена, например [b, c] или [a, d] и т.д.

Как я могу реализовать его самым простым способом?

  • 0
    Выберите каждый элемент с вероятностью X%. Если вы уже вывели X%, прекратите вывод любых других элементов.
  • 0
    @ merlin2011 это не сработает, если вы не дойдете до X%, если не пройдете его до тех пор, пока не достигнете X%
Показать ещё 1 комментарий
Теги:
random
skip

4 ответа

1
Лучший ответ

Первое решение:

double percentage = 50.0;
int max = (int)percentage * token.length;

int[] skip = new int[token.length];
int count = 0;
while(count < max)
{
    int rand = rnd.nextInt(token.length);
    if(skip[rand] == 0){
        skip[rand] = 1;
        count++;
    }
}

//Use a for loop to print token where the index of skip is 0, and skip index of those with 1.

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


Второе решение:

Convert your token of array to an arrayList.
int count = 0, x = 0;

while(printed < max){  //where max is num of elements to be printed

    int rand = rnd.nextInt(2); //generate 2 numbers: 50% chance

    if (rand == 0){
        System.out.println(list.get(x);
        list.remove(x);
        printed ++;
    }
    x++;
}

Сверните вероятность (например, вероятность 50%), следует ли печатать текущий элемент для каждой итерации. После того, как элемент напечатан, удалите его из списка, чтобы вы не печатали дубликаты.


Третье решение:

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

2

сначала вычислите сумму, чтобы пропустить ie (.50) * tokens.length (обратите внимание, что псевдокод)

Затем я бы создал массив длиной tokens.length и заполнил его с выбранным количеством 1, а остальные 0

т.е. для 50% из 10 [1,1,1,1,1,0,0,0,0,0]

Затем выполните простой алгоритм перетасовки (случайная перетасовка массива)

получить что-то вроде [0,1,1,0,0,1,0,1,1,0]

Затем, когда вы пропустите свой токенизатор, пройдитесь по этому массиву и проверьте

(if thisArray[i]==1){
  print(token);
}
1

Следующее использует алгоритм выбора подмножества Floyd для выбора случайного подмножества указанного размера. Это может быть излишним для небольшого количества токенов, но это довольно чертово эффективно для больших наборов.

import java.util.HashSet;

public class FloydsSubsetSelection {

   /*
    * Floyd algorithm to chose a random subset of m integers
    * from a set of n, outcomes are zero-based.
    */
   public static HashSet<Integer> generateMfromN(int m, int n) {
      HashSet<Integer> s = new HashSet<Integer>();
      for (int j = n-m; j < n; ++j) {
         if(! s.add((int)((j+1) * Math.random()))) {
            s.add(j);
         }
      }
      return s;
   }

   public static void main(String[] args) {
      // Stuff the tokens into an array.  I've used chars,
      // but these could be anything you want.  You can also
      // store them in any container which is indexable.
      char[] tokens = {'a', 'b', 'c', 'd', 'e', 'f'};
      int desired_percent = 50;     // change as desired

      // Convert desired percent to a count.  I added 1/2 to cause rounding
      // rather than truncation, change if different behavior is desired.
      int m = (int) (((desired_percent * tokens.length) + 0.5) / 100.0);
      HashSet<Integer> results = generateMfromN(m, tokens.length);
      for (int i: results) {                 // iterate through the generated subset
         System.out.print(tokens[i] + " ");  // to print the selected tokens
      }
      System.out.println();
   }
}
-2
 String line = value.toString();
   StringTokenizer tokenizer = new StringTokenizer(line);
   double percentage = 1.0 / 0.5 // replace 0.5 with the percentage you want
   int x = 0;
   while (tokenizer.hasMoreTokens()) {
         ++x;
         if (x >= percentage) {
              // print here
              x = 0;
         }
   }
  • 0
    это не делает то, что он просит
  • 0
    если процент = .5, вы можете получить 0 выбранных строк, если повезете вничью

Ещё вопросы

Сообщество Overcoder
Наверх
Меню