我不确定TreeMap
是否真的是最好的数据结构,但是。 。 。
您可以使用the Math.random()
method获取0.0
(含)和1.0
(不含)之间的随机值。然后,迭代你的地图元素,积累他们的频率,直到你超过这个值。首先超过此值的后缀是您的结果。假设你的地图元素的频率全部合计为1.0
,这将选择与它们的频率成比例的所有后缀。
例如:
public class Demo
{
private final Map<String, Double> suffixFrequencies =
new TreeMap<String, Double>();
private String getRandomSuffix()
{
final double value = Math.random();
double accum = 0.0;
for(final Map.Entry<String, Double> e : suffixFrequencies.entrySet())
{
accum += e.getValue();
if(accum > value)
return e.getKey();
}
throw new AssertionError(); // or something
}
public static void main(final String... args)
{
final Demo demo = new Demo();
demo.suffixFrequencies.put("abc", 0.3); // value in [0.0, 0.3)
demo.suffixFrequencies.put("def", 0.2); // value in [0.3, 0.5)
demo.suffixFrequencies.put("ghi", 0.5); // value in [0.5, 1.0)
// Print "abc" approximately three times, "def" approximately twice,
// and "ghi" approximately five times:
for(int i = 0; i < 10; ++i)
System.out.println(demo.getRandomSuffix());
}
}
注:
- 由于舍入误差,则可能
throw new AssertionError()
实际上将发生,每隔一段时间,尽管非常罕见。所以我建议你用一些总是选择第一个元素或最后一个元素或某物的东西来替换该行。
- 如果频率不是全部合计为1.0,那么您应该在
getRandomSuffix()
的开头处添加一个合格的合格数来确定所有频率的总和。然后您可以相应地缩放value
。
这个问题主要是数学问题吗? – durron597
数学不是困难的部分。我知道如果一个后缀出现一次并且子字符串在文本中出现两次,那么它的概率是1/2,因此在文本生成器中出现1/2的时间。但是,手头的问题是如何获取这些信息,并从中产生一个“随机”字符。 – user1547050