Вы можете получить небольшое сокращение объема вычислений с помощью небольшого рефакторинга, основанного на ассоциативных свойствах арифметики (и конкатенации строк), хотя я не уверен, что это изменит жизнь. Основная идея будет выглядеть следующим образом:
рассмотрим длинную строку, например 'abcdefghik', длиной 10, для определенности без потери общности. При наивном подходе вы умножаете p (a) на множество разделов хвоста 9, p (ab) на множество разделов хвоста 8 и т. Д .; в частности, p (a) и p (b) будут умножать те же самые разбиения 8-хвоста (все они), что и p (ab) - 3 умножения и две суммы среди них. Таким образом, коэффициент:
(p(ab) + p(a) * p(b)) * (partitions of the 8-tail)
и мы получили 2 умножения и 1 сумму для этой части, сохранив 1 продукт и 1 сумму. чтобы покрыть все разделы с точкой разделения справа от 'b'. Когда дело доходит до разделов с разделением справа от 'c',
(p(abc) + p(ab) * p(c) + p(a) * (p(b)*p(c)+p(bc)) * (partitions of the 7-tail)
экономия средств, отчасти благодаря внутреннему рефакторингу - хотя, конечно, нужно быть осторожным с двойным счетом. Я думаю, что этот подход может быть обобщен - начните с середины и рассмотрите все разделы, которые там разделены, отдельно (и рекурсивно) для левой и правой части, умножения и суммирования; затем добавьте все разделы, которые там не разбиты, например, в этом примере половинками являются «abcde» слева и «fghik» справа, вторая часть посвящена всем разделам, где «ef» вместе, а не друг от друга, поэтому «сверните» все вероятности, посчитав, что «ef» 'как новый' superletter 'X, и у вас осталась строка на одну короче,' abcdXghik '(конечно, вероятности для подстрок THAT отображаются непосредственно в оригиналы, например, p (cdXg) в новой строке просто в точности p (cdefg) в оригинале).