Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

Глава 12. Последовательности и динамическое программирование

substr (я, m): Возвратите подстроку S длины m начинающийся в индексе i.

найдите (Q): Если Q - подстрока S, возвратите индекс начала

из первого возникновения Q в S еще возвратите n, длину S.

c str (): Возвратите последовательность C-стиля, содержащую содержание S.

По умолчанию последовательность инициализирована к пустой последовательности. Последовательность может быть инициализирована от другой последовательности STL или от последовательности C-стиля. Не возможно, однако, инициализировать последовательность STL от единственного характера. Последовательности STL также поддерживают функции, которые возвращаются и вперед и обратный iterators. У всех операций, которые определены с точки зрения индексов целого числа, есть копии, которые основаны на iterators.

Класс последовательности STL также поддерживает назначение одной последовательности другому. Это про - vides относительные операторы, такой как ==, <> =, которые выполнены lexicograph-ically. Последовательности могут быть связаны, используя +, и мы можем приложить одну последовательность к другому использованию + =. Последовательности могут быть введены, используя>> и производят использование <<. func-tion getline (в, S) читает всю линию входа от входного потока в и назначает его на последовательность S.

Класс последовательности STL - фактически особый случай более общего templated класса, названного основной последовательностью <T>, который поддерживает все операции по последовательности, но позволяет ее элементам иметь произвольный тип, T, не просто случайную работу. Последовательность STL - просто короткий способ сказать основную последовательность <случайная работа>. «Ряд целых чисел» мог быть определен как основная последовательность <интервал>.

Пример 12.1: Рассмотрите следующий ряд операций, которые выполнены на последовательности S = «abcdefghijklmnop»:

Операция Продукция

S.size () 16 S.at (5) 'f' S[5] 'f' S + «qrs» «abcdefghijklmnopqrs» S == «abcdefghijklmnop» истинный S.find («топленое масло») 6S.substr (4, 6) «efghij» S.erase (4, 6) «abcdklmnop» S.insert (1, «xxx») «axxxbcdklmnop» S + = «xy» «axxxbcdklmnopxy» S.append («z») «axxxbcdklmnopxyz»

За исключением находки (Q) функция, которую мы обсуждаем в Разделе 12.3, все вышеупомянутые функции легко осуществлены просто, представляя последовательность как множество знаков.

12.2. Динамическое программирование 557

12.2 Динамическое Программирование

В этой секции мы обсуждаем динамический программный метод проектирования алгоритма. Эта техника подобна технике делить-и-побеждать (Раздел 11.1.1), в котором это может быть применено к большому разнообразию различных проблем. Есть немного al - gorithmic методы, которые могут взять проблемы, которые, кажется, требуют показательного времени и производят многочленно-разовые алгоритмы, чтобы решить их. Динамическое программирование - одна такая техника. Кроме того, алгоритмы, которые следуют из применений динамического программного метода, обычно довольно просты - часто бывший должный немного больше, чем несколько линий кодекса описать некоторые вложенные петли для того, чтобы заполнить стол.

12.2.1 Матричный продукт цепи

Вместо того, чтобы начинаться с объяснением общих компонентов dy-

namic программирование техники, мы начинаем, давая классику, конкретному примеру. Предположим, что нам дают коллекцию n двумерных множеств (матрицы), для которых мы хотим вычислить продукт

A = A0 ∙ A1 ∙ A2 ∙ ∙ ∙ 1,

где Ай - di di+1 матрица, поскольку я = 0, 1, 2..., n- 1. В стандартной матрице

алгоритм умножения (который является тем, который мы используем), чтобы умножить d электронная матрица B времена e f - матрица C, мы вычисляем продукт, A, как

e-1

[Я] [j] = å B [я] [k] ∙C [k] [j]. k =0

Это определение подразумевает, что матричное умножение ассоциативно, то есть, это подразумевает что B (C D) = (B∙C) D. Таким образом мы можем ввести выражение для любого пути

мы желаем, и мы все еще заканчиваем с тем же самым ответом. Мы не обязательно выступаем

то же самое число примитивных (то есть, скаляр) умножение в каждом parenthesiza-tion, однако, как иллюстрирован в следующем примере.

Пример 12.2: Позвольте B быть 2 с 10 матрицами, позволить C быть 10 с 50 матрицами, и позволить D быть

50 с 20 матрицами. Вычисление B (C D) требует 2 10 20 + 10 50 20 = 10, 400 умножения, тогда как, вычисляя (B∙C) D требует 2 10 50 + 2 50 20 = 3000

умножение.

Матричная проблема продукта цепи состоит в том, чтобы определить parenthesization

выражение, определяющее продукт, который минимизирует общее количество скаляра mul-tiplications выполненный. Поскольку пример выше иллюстрирует, различия между различными решениями могут быть существенными, настолько находящее хорошее решение может привести к signifi-ускорениям косяка.