<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=37.212.25.79&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=37.212.25.79&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/37.212.25.79"/>
		<updated>2026-04-25T18:12:17Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%B8%D0%BD%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%94%D0%9A%D0%90,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%BE%D0%BF%D0%BA%D1%80%D0%BE%D1%84%D1%82%D0%B0_(%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C_O(n_log_n))&amp;diff=33376</id>
		<title>Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%B8%D0%BD%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%94%D0%9A%D0%90,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A5%D0%BE%D0%BF%D0%BA%D1%80%D0%BE%D1%84%D1%82%D0%B0_(%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C_O(n_log_n))&amp;diff=33376"/>
				<updated>2013-11-04T11:21:46Z</updated>
		
		<summary type="html">&lt;p&gt;37.212.25.79: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Пусть дан автомат, распознающий определенный язык. Требуется найти [[ Эквивалентность_состояний_ДКА | эквивалентный автомат]] с наименьшим количеством состояний.&lt;br /&gt;
&lt;br /&gt;
== Минимизация ДКА ==&lt;br /&gt;
Если в ДКА существуют два [[ Эквивалентность_состояний_ДКА | эквивалентных состояния]], то при их объединении мы получим [[ Эквивалентность_состояний_ДКА | эквивалентный ДКА]], так как распознаваемый язык не изменится. Основная идея минимизации состоит в разбиении множества состояний на классы эквивалентности, полученные классы и будут состояниями минимизированного ДКА. &lt;br /&gt;
&lt;br /&gt;
== Простой алгоритм ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
Класс &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; '''разбивает''' класс &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;R_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R_2&amp;lt;/tex&amp;gt;, если &lt;br /&gt;
# &amp;lt;tex&amp;gt;\forall r \in R_1 \,\,\, \delta(r, a) \in S&amp;lt;/tex&amp;gt; &lt;br /&gt;
# &amp;lt;tex&amp;gt;\forall r \in R_2 \,\,\, \delta(r, a) \notin S&amp;lt;/tex&amp;gt; &lt;br /&gt;
}} &lt;br /&gt;
Если класс &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; может быть разбит по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, то он содержит хотя бы одну пару неэквивалентных состояний (так как существует строка которая их различает). Если класс нельзя разбить, то он состоит из эквивалентных состояний.&lt;br /&gt;
Поэтому самый простой алгоритм состоит в том, чтобы разбивать классы текущего разбиения до тех пор пока это возможно. &lt;br /&gt;
&lt;br /&gt;
Итеративно строим разбиение множества состояний следующим образом.&lt;br /&gt;
# Первоначальное разбиение множества состояний {{---}} класс допускающих состояний &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt; и класс недопускающих состояний &amp;lt;tex&amp;gt;Q \setminus F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Перебираются символы алфавита &amp;lt;tex&amp;gt;a \in \Sigma&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;(F, a)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(Q \setminus F, a)&amp;lt;/tex&amp;gt; помещаются в очередь.&lt;br /&gt;
# Из очереди извлекается пара &amp;lt;tex&amp;gt;(S, a)&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; далее именуется как сплиттер.&lt;br /&gt;
# Все классы текущего разбиения разбиваются на 2 подкласса (один из которых может быть пустым). Первый состоит из состояний, которые по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; переходят в сплиттер, а второй из всех оставшихся. &lt;br /&gt;
# Те классы, которые разбились на два непустых подкласса, заменяются этими подклассами в разбиении, а также добавляются в очередь.&lt;br /&gt;
# Пока очередь не пуста, выполняем п.3 – п.5.&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; {{---}} множество состояний ДКА.&lt;br /&gt;
&amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt; {{---}} множество терминальных состояний.&lt;br /&gt;
&amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt; {{---}} очередь.&lt;br /&gt;
&amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; {{---}} разбиение множества состояний ДКА.&lt;br /&gt;
&amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; {{---}} класс состояний ДКА.&lt;br /&gt;
  &amp;lt;tex&amp;gt;P \leftarrow \{ F, Q \setminus F \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  &amp;lt;tex&amp;gt;W \leftarrow \{ \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  '''for all''' &amp;lt;tex&amp;gt;a \in \Sigma&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.push'''(&amp;lt;tex&amp;gt;F, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.push'''(&amp;lt;tex&amp;gt;Q \setminus F, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  '''while not''' &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.isEmpty()''' &lt;br /&gt;
    &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.pop'''(&amp;lt;tex&amp;gt;S, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    '''for all''' &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; '''in''' &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; &lt;br /&gt;
      &amp;lt;tex&amp;gt;R_1 = R \cap \delta^{-1} (S, a) &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;R_2 = R \setminus R_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; |R_1| \ne 0&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;|R_2| \ne 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
        '''replace''' &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; '''in''' &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; '''with''' &amp;lt;tex&amp;gt;R_1&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;R_2&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.push'''(&amp;lt;tex&amp;gt;R_1, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
        &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.push'''(&amp;lt;tex&amp;gt;R_2, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
Когда очередь станет пустой, будет получено разбиение на классы эквивалентности, так как больше ни один класс невозможно разбить.&lt;br /&gt;
&lt;br /&gt;
===Время работы===&lt;br /&gt;
Время работы алгоритма оценивается как &amp;lt;tex&amp;gt;O(|\Sigma| \cdot n^2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; {{---}} количество состояний ДКА, а &amp;lt;tex&amp;gt; \Sigma &amp;lt;/tex&amp;gt;{{---}} алфавит. Это следует из того, что если пара &amp;lt;tex&amp;gt;(S, a)&amp;lt;/tex&amp;gt; попала в очередь, и класс &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; использовался в качестве сплиттера, то при последующем разбиении этого класса в очередь добавляется два класса &amp;lt;tex&amp;gt;S_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt;, причем можно гарантировать лишь следующее уменьшение размера: &amp;lt;tex&amp;gt;|S| \ge |S_i| + 1&amp;lt;/tex&amp;gt;. Каждое состояние изначально принадлежит лишь одному классу в очереди, поэтому каждый переход в автомате будет просмотрен не более, чем &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; раз. Учитывая, что ребер всего &amp;lt;tex&amp;gt;O(|\Sigma| \cdot n)&amp;lt;/tex&amp;gt;, получаем указанную оценку.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм Хопкрофта==&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement = Класс &amp;lt;tex&amp;gt;R = R_1 \cup R_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R_1 \cap R_2 = \varnothing&amp;lt;/tex&amp;gt;, тогда разбиение всех классов (текущее разбиение) по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; любыми двумя классами из &amp;lt;tex&amp;gt;R, R_1, R_2&amp;lt;/tex&amp;gt; эквивалентно разбиению всех классов с помощью &amp;lt;tex&amp;gt;R, R_1, R_2&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof = &lt;br /&gt;
Разобьем все классы с помощью &amp;lt;tex&amp;gt;R &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; R_1&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, тогда для любого класса &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; из текущего разбиения выполняется&lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \in R&amp;lt;/tex&amp;gt; and &amp;lt;tex&amp;gt; \delta(r, a) \in R_1&amp;lt;/tex&amp;gt; or &lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \in R&amp;lt;/tex&amp;gt; and &amp;lt;tex&amp;gt; \delta(r, a) \notin R_1&amp;lt;/tex&amp;gt; or &lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \notin R&amp;lt;/tex&amp;gt; and &amp;lt;tex&amp;gt; \delta(r, a) \notin R_1&amp;lt;/tex&amp;gt;  &lt;br /&gt;
А так как &amp;lt;tex&amp;gt;R = R_1 \cup R_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R_1 \cap R_2 = \varnothing&amp;lt;/tex&amp;gt; то выполняется&lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \in R_2 &amp;lt;/tex&amp;gt; or &lt;br /&gt;
:&amp;lt;tex&amp;gt; \forall r \in B \,\,\, \delta(r, a) \notin R_2&amp;lt;/tex&amp;gt; &lt;br /&gt;
Из этого следует, что разбиение всех классов с помощью &amp;lt;tex&amp;gt;R_2&amp;lt;/tex&amp;gt; никак не повлияет на текущее разбиение. &amp;lt;br/&amp;gt;&lt;br /&gt;
Аналогично доказывается и для разбиения с помощью &amp;lt;tex&amp;gt;R &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; R_2&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
Разобьем все классы с помощью &amp;lt;tex&amp;gt;R_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; R_2&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, тогда для любого класса &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; из текущего разбиения выполняется&lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \in R_1&amp;lt;/tex&amp;gt; and &amp;lt;tex&amp;gt; \delta(r, a) \notin R_2&amp;lt;/tex&amp;gt; or &lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \notin R_1&amp;lt;/tex&amp;gt; and &amp;lt;tex&amp;gt; \delta(r, a) \in R_2&amp;lt;/tex&amp;gt; or &lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \notin R_1&amp;lt;/tex&amp;gt; and &amp;lt;tex&amp;gt; \delta(r, a) \notin R_2&amp;lt;/tex&amp;gt;  &lt;br /&gt;
А так как &amp;lt;tex&amp;gt;R = R_1 \cup R_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R_1 \cap R_2 = \varnothing&amp;lt;/tex&amp;gt; то выполняется&lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \in R &amp;lt;/tex&amp;gt; or &lt;br /&gt;
:&amp;lt;tex&amp;gt; \forall r \in B \,\,\, \delta(r, a) \notin R&amp;lt;/tex&amp;gt; &lt;br /&gt;
Из этого следует, что разбиение всех классов с помощью &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; никак не повлияет на текущее разбиение.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Алгоритм Хопкрофта отличается от простого тем, что иначе добавляет классы в очередь.&lt;br /&gt;
Если класс &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; уже есть в очереди, то согласно лемме можно просто заменить его на &amp;lt;tex&amp;gt;R_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R_2&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Если класса &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; нет в очереди, то согласно лемме в очередь можно добавить класс &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; и любой из &amp;lt;tex&amp;gt;R_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R_2&amp;lt;/tex&amp;gt;, а так как для любого класса &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; из текущего разбиения выполняется &lt;br /&gt;
:&amp;lt;tex&amp;gt;\forall r \in B \,\,\, \delta(r, a) \in R &amp;lt;/tex&amp;gt; or &lt;br /&gt;
:&amp;lt;tex&amp;gt; \forall r \in B \,\,\, \delta(r, a) \notin R&amp;lt;/tex&amp;gt; &lt;br /&gt;
то в очередь можно добавить только меньшее из &amp;lt;tex&amp;gt;R_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R_2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; {{---}} множество состояний ДКА.&lt;br /&gt;
&amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt; {{---}} множество терминальных состояний.&lt;br /&gt;
&amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt; {{---}} очередь.&lt;br /&gt;
&amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; {{---}} разбиение множества состояний ДКА.&lt;br /&gt;
&amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; {{---}} класс состояний ДКА.&lt;br /&gt;
  &amp;lt;tex&amp;gt;P \leftarrow \{ F, Q \setminus F \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  &amp;lt;tex&amp;gt;W \leftarrow \{ \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
  '''for all''' &amp;lt;tex&amp;gt;a \in \Sigma&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.push'''('''min'''(&amp;lt;tex&amp;gt;F, Q \setminus F&amp;lt;/tex&amp;gt;), &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
  '''while not''' &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.isEmpty()''' &lt;br /&gt;
    &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.pop'''(&amp;lt;tex&amp;gt;S, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    '''for each''' &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; '''in''' &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; '''split by''' &amp;lt;tex&amp;gt;(S, a)&amp;lt;/tex&amp;gt;  &lt;br /&gt;
      '''replace''' &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; '''in''' &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; '''with''' &amp;lt;tex&amp;gt;R_1&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;R_2&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' (&amp;lt;tex&amp;gt;R, a&amp;lt;/tex&amp;gt;) '''in''' &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;&lt;br /&gt;
        '''replace''' (&amp;lt;tex&amp;gt;R, a&amp;lt;/tex&amp;gt;) '''in''' &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt; '''with''' (&amp;lt;tex&amp;gt;R_1, a&amp;lt;/tex&amp;gt;) '''and''' (&amp;lt;tex&amp;gt;R_2, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''else'''&lt;br /&gt;
        '''if''' &amp;lt;tex&amp;gt; |R_1| \le |R_2|&amp;lt;/tex&amp;gt;&lt;br /&gt;
          &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.push'''(&amp;lt;tex&amp;gt;R_1, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
        '''else'''&lt;br /&gt;
          &amp;lt;tex&amp;gt;W&amp;lt;/tex&amp;gt;'''.push'''(&amp;lt;tex&amp;gt;R_2, a&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
===Время работы===&lt;br /&gt;
Время работы модифицированного алгоритма оценивается как &amp;lt;tex&amp;gt;O(|\Sigma| \cdot n\log{n})&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; {{---}} количество состояний ДКА, а &amp;lt;tex&amp;gt; \Sigma &amp;lt;/tex&amp;gt;{{---}} алфавит. В данном случае при последующем разбиении в очередь будет добавлен класс &amp;lt;tex&amp;gt;S_1&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|S| \ge 2|S_1|&amp;lt;/tex&amp;gt;. Каждый переход в автомате будет просмотрен не более, чем &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt; раз, ребер всего &amp;lt;tex&amp;gt;O(|\Sigma| \cdot n)&amp;lt;/tex&amp;gt;, отсюда указанная оценка.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — М.: Издательский дом «Вильямс», 2002. — С. 177 — ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
* ''D. Gries.'' Describing an algorithm by Hopcroft. Technical Report TR-72-151, Cornell University, December 1972.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>37.212.25.79</name></author>	</entry>

	</feed>