Pull to refresh
141
60
Иван Бессонов @ibessonov

Математик, программист

Send message

Возможно не стоило наследоваться от Future, дабы не нарушать ожидаемый контракт от предыдущей работы с Future.

С этом не могу не согласиться, это действительно сомнительное решение.

PS: Я надеюсь вы понимаете, что мы просто холиварим?

Конечно!

Извините, но это звучит это как оправдание "Ну да фигово я реализовал, НО в документации же в таком-то файле на такой-то строчке я об этом написал"

Кажется вы от класса, который заявляет A, ожидаете, что он будет делать B. CompletableFuture - это всего-лишь инструмент. Он написан в точности таким, каким он был задуман, никакого вопроса про "не успевали" тут быть не может. Если для вашей задачи он не подходит, то ничего страшного - возьмите другой. Если вы по какой-то причине считаете, что этот инструмент должен делать что-то иначе, т.е. концептуально быть другим инструментом, то может быть это вопрос именно ваших ожиданий.

Если кто-то объснит, то буду благодарен

Это из другого вашего сообщения. В статье есть ответ, в документации тоже. Не нужно ожидать, что CompletableFuture делает то же самое, что RxJava, даже не прочитав документацию, тут именно вы совершаете ошибку, а не разработчики Java.

Нет, я отказываюсь повышать сложность :)
Хотя посмотрим, спасибо!

Идеи есть, конечно. CompletableFuture полностью отвязана от потоков ради большей гибкости.
Да и завершать задачи через флаг прерывания потока - как то грубовато это на мой взгляд, не всегда удобно, свой статус операции намного универсальнее

Это же и в документации сказано:

    /**
     * If not already completed, completes this CompletableFuture with
     * a {@link CancellationException}. Dependent CompletableFutures
     * that have not already completed will also complete
     * exceptionally, with a {@link CompletionException} caused by
     * this {@code CancellationException}.
     *
     * @param mayInterruptIfRunning this value has no effect in this
     * implementation because interrupts are not used to control
     * processing.
     *
     * @return {@code true} if this task is now cancelled
     */
    public boolean cancel(boolean mayInterruptIfRunning) {

Справедливый вопрос. Я не описал, что именно имею ввиду под head.
На первой итерации head - это первые 2 нуля, а у вас в обозначениях head - это то, что находится перед этими двумя нулями. Т.е. просто разница в нотации, код вы поняли совершенно верно.

И это бы прекрасно сработало в случае RxJava, но невозможно в случае стандартного CompletableFuture.

Да, тут проблема именно в использовании CompletableFuture - она работает не так, как RxJava, и cancel не приводит к интеррапту потока даже если передать флаг mayInterruptIfRunning=true.
Эти нюансы хорошо задокументированы, и если разработчик полагался на предполагаемое поведение, которого не существует - это ошибка самого разработчика.

Да, опечатка. Поправил, спасибо большое!

"Функциональное программирование". Денис, ну Вы чего, здесь же его нет

Как правило не входит, это дополнительное ограничение, которое задаётся только явным образом

Про такие слова в статье есть информация, но уже ближе к концу. Рекуррентное соотношение в том виде, в каком оно дано в начале, для fuf строить нельзя, вы правы

Вероятность при этом можно определить как матожидание периода выпадения благоприятного исхода

В конце вы предложили нормальное определение, через отношение. С ним я согласен. Но вот с 17/26^4 я согласиться не могу, это неправильный ответ, и в статье сказано почему. Количество событий в числителе просто не такое, проверьте те же рассуждения хотя бы для строк длиной 8, для них можно получить точный ответ на листке бумаги, это 5*26^4-1. Единицу отнимать - обязательно, потому что она соответствует строке с двумя вхождениями плохого слова.
Я не усложняю решение, это вы пытаетесь его упростить, при этом допускаете ошибку в рассуждениях. Пожалуйста, ознакомьтесь с содержанием статьи ещё раз, спасибо!

Определение вероятности выглядит совершенно иначе, в нём не участвует бесконечный поток символов.
Так или иначе, вы повторили распространённую ошибку, связанную с числом 17. В статье объяснено, почему этот ответ неверный. В комментариях к статье есть более подробные объяснения.

Блин, не сразу заметил, что это сообщения от двух разных людей. То то я и думал, что-то не стыкуется немного стиль оформления и размышления) Мне нужно быть внимательнее

В такой формулировке гораздо понятнее, спасибо!
Да, этой формуле мне противопоставить нечего, она выглядит совершенно верной.

Но я не складываю вероятности.

Я затупил, извиняюсь, там действительно возведение в степень.
Попробую объяснить, почему возведение в степень даёт неточный ответ. Формулу возведения в степень вы, я полагаю, взяли из схемы Бернулли (https://ru.wikipedia.org/wiki/Схема_Бернулли) как частный случай. Для того, чтобы схема Бернулли работала, у вас должна быть последовательность независимых событий.
Цитирую: результат очередного эксперимента не должен зависеть от результатов предыдущих экспериментов.
В случае же, когда вы движетесь по конкретному слову и проверяете его подслова, события являются зависимыми. Например, после прочтения слова FUCK, следующим словом для проверки будет UCK* - т.е. 100% не FUCK. Вероятность следующего события зависит от предыдущего события. Т.е. не соблюдены необходимые условия примения формулы. Надеюсь так яснее.
Ещё раз извиняюсь за свой затуп в прошлом комментарии. Если говоришь кому-то, что он не прав, самому лучше не ошибаться :)

  1. Нам известна вероятность встретить хотя-бы раз слово FUCK в строке.

Неизвестна, это именно та вероятность, которую я искал в статье, но допустим. Кажется вы поставили задачу "найти вероятность встретить FUCK ровно один раз".
Её можно решать предложенным вами подходом, но очень сложно.

Мы можем (можем же?) посчитать вероятность встретить слово FUCK два раза в строке

Наверное? Повторюсь, кажется очень сложным.
А вообще, согласно приведённой схеме, для того, чтобы посчитать вероятность вхождения ровно один раз, мы должны посчитать вероятность вхождения ровно два раза. Это кажется контринтуитивным, как будто решаем более сложную задачу ради более простой. Думаю, что такой путь никуда нас не приведёт.

Проблема в том, что для умножения вероятностей применяется лишь в конкретных случаях. Но это даже не важно, потому что вы, скорее всего, имели ввиду умножение на 17, а не возведение в 17-ю степень, то есть сумму вероятностей (это же подтверждает ваш ответ, не совпадающий с тем, что дала бы формула).
Почти та же самая формула рассмотрена в статье, в разделе 2 про аппроксимацию. Под статьёй, в комментариях, было приведено множество дополнительных аргументов в пользу того, что аппроксимация неточная.
Ваша же конкретная формула ошибочна по той же причине - вы складываете вероятности событий, которые пересекаются. В этом случае необходимо вычитать вероятности пересечения. Нельзя просто взять и умножить на 17, это так не работает :)

    private static final String ETALON = "2143";
    private static final int K = 5, N = 10;

    public static void main(String[] args) {
        // K ^ N
        long kn = 1;

        for (int i = 0; i < N; i++) {
            kn *= K;
        }

        long count = 0;

        for (long i = 0; i < kn; i++) {
            // Format string with 0 padding.
            String str = Long.toString(i + kn, K).substring(1);

            if (str.contains(ETALON)) {
                count++;
            }
        }

        System.out.println(count + " / " + kn);
    }

Ответ тот же, что я дал вчера: 109225 / 9765625

У вас вышло 109375 / 9 765 625.
Точный ответ, если я не ошибся при вычислении на телефоне (код напишу уже утром) - 109225 / 9 765 625.
То есть чуть-чуть меньше. И это легко проверяется полным перебором в программе.
Точность вероятностной проверки не позволит вам доказать правильность вашей формулы, потому что погрешность вычисления получается больше, чем ошибка формулы.

1
23 ...

Information

Rating
83-rd
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity

Specialization

Database Developer
Lead