Created
July 10, 2018 21:30
-
-
Save mashumafi/de528aeb367e80fd590ef08c30e75072 to your computer and use it in GitHub Desktop.
Choose a random words based on weights
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.AbstractCollection; | |
import java.util.Iterator; | |
import java.util.Random; | |
import java.util.Vector; | |
public class RandomWord { | |
public static void main(String []args){ | |
Vector<Item<String>> words = new Vector<Item<String>>(); | |
words.add(new Item<String>("Hello", 3)); | |
words.add(new Item<String>("World", 1)); | |
words.add(new Item<String>("Mouse", 2)); | |
words.add(new Item<String>("Cat", 4)); | |
words.add(new Item<String>("Dog", 8)); | |
test(words, 0, "Hello"); | |
test(words, 1, "Hello"); | |
test(words, 2, "Hello"); | |
test(words, 3, "World"); | |
test(words, 4, "Mouse"); | |
test(words, 5, "Mouse"); | |
test(words, 6, "Cat"); | |
test(words, 7, "Cat"); | |
test(words, 8, "Cat"); | |
test(words, 9, "Cat"); | |
test(words, 10, "Dog"); | |
test(words, 11, "Dog"); | |
test(words, 12, "Dog"); | |
test(words, 13, "Dog"); | |
test(words, 14, "Dog"); | |
test(words, 15, "Dog"); | |
test(words, 16, "Dog"); | |
test(words, 17, "Dog"); | |
String word = ItemChooser.choose(words); | |
System.out.println("Your random word is: " + word); | |
} | |
static void test(AbstractCollection<Item<String>> collection, int num, String expect) { | |
String word = ItemChooser.choose(collection, new FixedNumberGenerator(num)); | |
if(word != expect) { | |
System.out.println("Item at " + num + " is not " + expect); | |
} | |
} | |
} | |
class Item<T> { | |
public Item(T value, int weight) { | |
this.value = value; | |
this.weight = weight; | |
} | |
public T value; | |
public int weight; | |
} | |
class ItemChooser { | |
public static <T> T choose(AbstractCollection<Item<T>> collection, NumberGenerator generator) { | |
// Step 1: Calculate the weight | |
Iterator<Item<T>> iter = collection.iterator(); | |
int totalWeight = 0; | |
while(iter.hasNext()) { | |
totalWeight += iter.next().weight; | |
} | |
// Step 2: Calculate random number based on totalWeight | |
int selectedWeight = generator.nextInt() % totalWeight; | |
// Step 3: Choose the word based on selectedWeight | |
iter = collection.iterator(); | |
int sumWeight = 0; | |
Item<T> selected = null; | |
while(iter.hasNext()) { | |
selected = iter.next(); | |
sumWeight += selected.weight; | |
if(selectedWeight < sumWeight) { | |
break; | |
} | |
} | |
return selected.value; | |
} | |
public static <T> T choose(AbstractCollection<Item<T>> collection) { | |
return choose(collection, new RandomNumberGenerator()); | |
} | |
} | |
interface NumberGenerator { | |
int nextInt(); | |
} | |
class RandomNumberGenerator implements NumberGenerator { | |
Random generator = new Random(); | |
public int nextInt() { | |
return generator.nextInt(); | |
} | |
} | |
class FixedNumberGenerator implements NumberGenerator { | |
int num; | |
FixedNumberGenerator(int num) { | |
this.num = num; | |
} | |
public int nextInt() { | |
return num; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment