我必须生成一个可能的每个字符串的列表(给定一个特定的字符串来从中挑选字符),我想出的第一个方法就是这个:
public String getRandomLetters(Integer size, String range){
String word = "";
Random r = new Random();
for (int i = 0; i < size; i++) {
word += range.charAt(r.nextInt(range.length()));
}
return word;
}
像这样使用:getRandomLetters(2, "abc");
这将返回一个包含2个字母的字符串。
现在,有了这个给定的范围,我必须生成一个随机字符串列表。这个单词列表必须没有可重复的单词,必须以1个字符开头,当有可能时只添加另一个单词。
我试着这个:
public List<String> getListOfRandomWords(Integer listLenght){
String range = "abc"; //abcdefghijklmnopqrstuvwxyz
Integer rangeLenght = range.length();
List<String> words = new ArrayList();
int counter = 1;
int possibilities = (int) Math.pow(Double.valueOf(rangeLenght), Double.valueOf(counter));
String word = "";
for (int i = 0; i < listLenght; i++) {
word = getRandomLetters(counter, range);
while (words.contains(word)) {
if(words.size() == possibilities){
counter++;
possibilities += (int) Math.pow(Double.valueOf(rangeLenght), Double.valueOf(counter));
}
word = getRandomLetters(counter, range);
}
words.add(word);
}
return words;
}
运行此:
List<String> testList = getListOfRandomWords(20);
for (String block : testList) {
System.out.println(block);
}
输出:
c
b
a
cc
ca
aa
bb
ba
ac
bc
ab
cb
bcc
cca
bac
aab
bab
cbb
baa
bcb
输出正常且方法正常,我唯一关心的是while(randomLetters.contains(randomLetter))
,这是检查重复值的最佳方法吗?
PD:我不能使用和来使这更容易并按顺序生成字符串,它们必须按随机顺序排列。
答案 0 :(得分:0)
使用List<String> words = new ArrayList<>();
和words.contains(word)
绝对不是检查重复值的最佳方式。这是一个O(N²)操作,因为你对每个单词进行了O(N)搜索,并且对于你添加的每个单词都要循环一次或多次。
Set<String> words = new HashSet<>();
和words.contains(word)
应该明显加快。
当然,如果您想维护您添加了单词的顺序,而不是一些随机顺序,那么您需要使用:Set<String> words = new LinkedHashSet<>();
。
使用return new ArrayList<>(words)
将返回的值转换回List<String>
。
答案 1 :(得分:0)
我发现循环遍历所有排列的最佳方式是Heap's algorithm。
我完全不理解它,因为我没有阅读它背后的证据,但它绝对有效,并且只需要在所有排列中循环一次。使用随机置换生成器永远不能保证生成所有排列。
答案 2 :(得分:0)
Random和Unique不能一起满足。因此,假设您需要所有排列的随机 order 。
如果字符串的长度相对较小(因此结果列表适合内存),您可以先生成所有排列,然后再生成随机播放结果。这将提供相当不错的性能,因为两个操作在输出大小上是线性的。
获取代码组合Smart way to generate permutation and combination of String和Random shuffling of an array
如果一次只需要一个随机唯一结果 - 生成随机字符串的原始代码是可以的,但您应该使用Hashset或类似结构来查找重复项(Fastest data structure for contains() in Java?)。
请注意,以这种方式生成所有组合是不切实际的 - 在大约80%的组合之后,重试次数将增长得非常大,并且最终会接近所有组合的数量。
或者,您可以直接将随机数转换为字符串: