Ваш псевдокод дает алгоритм в O (2 ^ n).Я думаю, что вы можете иметь что-то в O (n ^ 3).
Прежде всего, давайте посмотрим на сложность вашего алгоритма.Допустим, что количество операций, необходимых для проверки скобок, составляет T(n)
.Если я правильно понял, ваш алгоритм состоит из:
Разрежьте выражение на две (n-1 возможностей)
Проверьте, если слева иправая часть имеет соответствующие скобки.
Итак T(n)
= checking if you cut at the first place
+ checking if you cut at the second place
+ ... + checking if you cut at the last place
T(n)
= T(1)+T(n-1)
+ T(2)+T(n-2)
+ ... + T(n-1)+T(1)
+ n
Немного вычислений скажет вам, что T(n) = 2^n*T(1) + O(n^2) = O(2^n)
Моя идея состоит в том, что вам нужно толькоэто проверка на наличие скобок являются «подслов».«Subword_i_j» состоит из всех букв между положением i и положением j.Конечно, i<j
, поэтому у вас есть N*(N-1)/2
подслов.Допустим, L[i][j]
- это число допустимых скобок для subword_i_j.Для удобства я забуду другие значения M[i][j]
, в которых указывается число круглых скобок, которое приводит к значению false, но не забывайте, что оно здесь!
Вы хотите вычислить все возможные подсловначиная с самых маленьких (размер 1) до самого большого (размер N).
Вы начинаете с вычисления L[i][i]
для всех i.Есть N таких значений.Это легко, если i-й литерал - True, тогда L[i][i]=1
else L[i][i]=0
.Теперь вы знаете число скобок для всех подслов размера 1.
Допустим, вы знаете скобки для всех подслов размера S.
Затем вычислите L[i][i+S]
для i между 1и NS.Это подслова размера S + 1.Он состоит из разбиения подслова всеми возможными способами (S-способы), и проверки, является ли левая часть (которая является подсловом размера S1 <= S) <strong>и правой частью (который имеет размер S2 <= S) <strong>и , операторы между (или, xor, и) совместимы.Есть S * (NS) таких значений.
Наконец, вы получите L[1][N]
, который сообщит вам, если есть допустимые скобки.
Стоимость:
checking subwords of size 1
+ checking subwords of size 2
+ ... + checking subwords of size N
= N
+ N-1
+ 2*(N-2)
+ 2*(N-2)
+ .. + (N-1)*(1)
= O(N^3)
Причина, по которой сложность лучше, состоит в том, что в вашем псевдокоде вы проверяете несколько раз одни и те же подслова без сохранения результата в памяти.
Редактировать: Arglllll, я пропустил предложение we save all the solutions to subproblems and read them when we meet them again. thus save time.
,Ну, кажется, что если вы это сделаете, у вас также есть алгоритм в худшем случае O (N ^ 3).Не думай, что ты сможешь добиться гораздо большего ...