У меня есть код 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] и т.д.
Как я могу реализовать его самым простым способом?
Первое решение:
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%) элементов из вашего токена. Просто распечатайте остальные. Это, наверное, один из самых простых способов, о которых я могу думать.
сначала вычислите сумму, чтобы пропустить 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);
}
Следующее использует алгоритм выбора подмножества 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();
}
}
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;
}
}