Генерация букв с заданными частотами в C#

В этом примере генерируются случайные буквы с частотами, которые они имеют в обычном английском тексте. Следующий код показывает, как этот пример запускается.

// Частоты букв. Видеть:
// http://en.wikipedia.org/wiki/Letter_frequency
private float[] Frequencies =
{
    8.167f, 1.492f, 2.782f, 4.253f, 12.702f, 
    2.228f, 2.015f, 6.094f, 6.966f, 0.153f, 
    0.772f, 4.025f, 2.406f, 6.749f, 7.507f, 
    1.929f, 0.095f, 5.987f, 6.327f, 9.056f, 
    2.758f, 0.978f, 2.360f, 0.150f, 1.974f, 
    0.074f
};

// Генератор случайных чисел.
private Random Rand = new Random();

// Значение ASCII A.
private int int_A = (int)'A';

// Удостоверьтесь, что частоты составляют до 100.
private void Form1_Load(object sender, EventArgs e)
{
    // Дайте разницу E.
    float total = Frequencies.Sum();
    float diff = 100f - total;
    Frequencies[(int)'E' - int_A] += diff;
}

В массиве Frequencies содержатся относительные процентные частоты букв, перечисленные в Wikipedia . Этот пример рассматривает эти числа как проценты, так что, например, буква A должна появиться примерно в 8,176% времени. Если эти числа являются некоторыми другими значениями, такими как фракции между 0 и 1, вы можете соответствующим образом настроить программу. Если они подсчитываются, например, количество вхождений в определенном фрагменте текста, вы можете добавить их для преобразования их в проценты.

Код создает объект Random и определяет значение буквы A как целое для дальнейшего удобства.

Обработчик событий Load в форме добавляет все значения в Frequencies. В этом примере частоты не составляют до 100%, потому что они не на странице Википедии, где я их получил. Чтобы сделать общее количество до 100%, код добавляет их, вычитает общее количество из 100 и добавляет разницу в букву E, увеличивая или уменьшая частоту E немного, так что общее количество составляет 100%.

При нажатии кнопки «Создать» выполняется следующий код.

// Генерируем случайные буквы с указанными частотами.
private void btnGenerate_Click(object sender, EventArgs e)
{
    // Следите за количеством каждой сгенерированной буквы.
    int[] counts = new int[26];

    // Создаем буквы.
    int num_letters = int.Parse(txtNumLetters.Text);
    string result = "";
    for (int i = 0; i < num_letters; i++)
    {
        // Создаем число от 0 до 100.
        double num = 100.0 * Rand.NextDouble();

        // См., Какую букву это представляет.
        for (int letter_num = 0; ; letter_num++)
        {
            // Вычитаем частоту этого письма из числа.
            num -= Frequencies[letter_num];

            // Если num & lt; = 0, то это будет буква.
            if ((num <= 0) || (letter_num == 25))
            {
                char ch = (char)(int_A + letter_num);
                result += ch.ToString() +' ';
                counts[letter_num]++;
                break;
            }
        }
    }

    txtLetters.Text = result;
    txtLetters.Select(0, 0);

    // Отображение частот.
    lstFrequencies.Items.Clear();
    for (int i = 0; i < counts.Length; i++)
    {
        char ch = (char)(int_A + i);
        float frequency = (float)counts[i] / num_letters * 100;
        string str = string.Format("{0}\t{1,6}\t{2,6}\t{3,6}",
            ch.ToString(),
            frequency.ToString("0.000"),
            Frequencies[i].ToString("0.000"),
            (frequency - Frequencies[i]).ToString("0.000"));
        lstFrequencies.Items.Add(str);
    }
}

Для каждой из букв, которые он должен сгенерировать, программа выбирает случайное число между 0 (включительно) и 100 (исключение). Затем он перебирает значения в массиве частот, вычитая их из случайного значения. Когда случайное значение достигает 0, программа использует букву, соответствующую самой последней вычитаемой частоте. Предполагая, что Random генерирует числа с достаточно равномерным распределением (и это довольно хорошо), это означает, что каждая буква выбрана примерно с той же частотой, что и в массиве Frequencies.

Источник: http://csharphelper.com/blog/2017/11/generate-letters-with-given-frequencies-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector