Java - 获取字符频率,创建概率,然后生成伪随机字符

时间:2012-11-19 21:22:56

标签: java hashtable markov

我正在使用Markov模型创建一个伪随机文本生成器。基本上,我使用哈希表来存储顺序k的子串列表(马尔可夫模型的顺序),然​​后对于每个子串,我有一个后缀的TreeMap及其在整个子串中的频率。

我正在努力生成随机后缀。对于每个子字符串,我有一个包含所有可能后缀及其频率的TreeMap。我无法使用它为每个后缀创建概率,然后根据概率生成伪随机后缀。

对此概念的任何帮助以及如何执行此操作表示赞赏。如果您有任何问题或需要澄清,请告诉我。

1 个答案:

答案 0 :(得分:1)

我不确定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