Использование числового массива для корректировки шансов конкретного возвращаемого значения? - PullRequest
0 голосов
/ 26 декабря 2018

Я создаю метод с именем getRandomLetter(), который хочу случайным образом вернуть одну букву из английского алфавита.Я хочу, чтобы метод с большей вероятностью возвращал букву с более высоким числом, связанным с ним.

У меня есть два массива.У каждого есть символы для каждой буквы в алфавите.Второй имеет двойные числа, каждый из которых представляет вероятность того, что буква с тем же индексом в другом массиве будет буквой, возвращенной моим методом.

Я пытаюсь, чтобы метод имел разные шансы вернуть разные буквы в соответствии со значениями в массивах.

К сожалению, мой метод возвращает только z и y.

Как я могу заставить getRandomLetter() возвращать определенные буквы / символы в соответствии с числами, которые я указываю для каждого?

Пример моего кода:

public class MCVE {
    // each letter's frequency is represented in the next array by
    // the double value at the same index as the letter
    final private static char[] CharArr = "abcdefghijklmnopqrstuvwxyz".toCharArray();
    // Holds each letter's percentage-chance to be chosen
    // For Example: 0.1 is equal to 10%
    // All-together, they add up to 1.0
    final private static double[] DoubleArr = new double[] {
            0.087248322147651, 0.035722017752760335, 0.08010391859709894,
            0.05520675470881143, 0.046763368694522627, 0.018618748646893266,
            0.028144620047629357, 0.021866204806235117, 0.016020783719419788,
            0.07101104135094176, 0.06040268456375839, 0.08703182507036156,
            0.10002164970772895, 0.027711625893050443, 0.009742368478025547,
            0.021433210651656202, 0.0012989824637367395, 0.0458973803853648,
            0.07988742151980949, 0.05260878978133795, 0.0015154795410261962,
            0.022515696038103484, 0.009309374323446633, 0.0012989824637367395,
            0.011690842173630657, 0.006927906473262611};

    private static char getRandomLetter() {
        double randomDouble = ThreadLocalRandom.current().nextDouble(0.0, 1.0);

        char retVal = ' ';
        // subtract each value in DoubleArr from randomDouble until,
        // randomDouble would be < 0, then return the char that is
        // associated with that double
        for(int i = 0; i < CharArr.length; i++) {

            double subtract = DoubleArr[i];
            if (randomDouble - subtract <= 0.0)
                retVal = CharArr[i];
            else
                randomDouble -= subtract;
        }
        return retVal;
    }

    public static void main(String[] args) {
        // get a large sample of chars to test thoroughness
        char[] sampleChars = new char[1000];
        for(int i = 0; i < 1000; i++) {
            sampleChars[i] = getRandomLetter();
        }

        // print 10 characters per line
        int ct = 0;
        for(char c: sampleChars) {
            System.out.print(c + " ");
            ct++;
            if(ct == 10) {
                ct = 0;
                System.out.println();
            }
        }
    }
}

Пример того, что возвращается:

zzzzzzzzzz

zzyzzyzzzz

zzyzzzzzzz

zyzzzzzzzz

zzzzzzzzzz

zzzzzzzzyy

zzzzzzzzzz

zyzzzzzzzz

zzzzyzyzzz

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Вам, кажется, не нужен CharArray, вместо этого простой цикл со счетчиком int и циклом while, который проверяет этот счетчик и аккумулятор на предмет вашей вероятности.Мол,

private static char getRandomLetter() {
    double randomDouble = ThreadLocalRandom.current().nextDouble(), v = 0;
    int p = 0;
    while (p < DoubleArr.length && v <= randomDouble) {
        v += DoubleArr[p++];
    }
    return (char) ('a' + Math.min(p, 26) - 1);
}

Без каких-либо других изменений ваш код работает нормально. Примечание Поведение по умолчанию nextDouble() - это указанные вами границы.

0 голосов
/ 26 декабря 2018

Кажется, вы не "выпрыгнули" из цикла for , когда получили правильный ответ.Возможно, ваш getRandomLetter должен быть изменен на:

for(int i = 0; i < CharArr.length; i++) {

        double subtract = DoubleArr[i];
        if (randomDouble - subtract <= 0.0) {
             retVal = CharArr[i];
             break;
        }
        else
            randomDouble -= subtract;
    }
...