Правки по lab2
BIN
lab2/img/ka.png
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 172 KiB |
BIN
lab2/img/nka.png
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
@@ -27,25 +27,28 @@ class FiniteAutomaton:
|
||||
|
||||
for char in input_string:
|
||||
if char not in self.alphabet:
|
||||
return f"Символ '{char}' не из алфавита", transitions_path
|
||||
return f"Символ '{char}' не из алфавита ✗", transitions_path
|
||||
|
||||
next_state = self._get_next_state(current_state, char)
|
||||
|
||||
if next_state is None:
|
||||
return "Строка не соответствует", transitions_path
|
||||
return "Строка не соответствует ✗", transitions_path
|
||||
|
||||
transitions_path.append(next_state)
|
||||
current_state = next_state
|
||||
|
||||
return (
|
||||
"Строка соответствует"
|
||||
"Строка соответствует ✓"
|
||||
if current_state in self.final_states
|
||||
else "Строка не соответствует"
|
||||
else "Строка не соответствует ✗"
|
||||
), transitions_path
|
||||
|
||||
def generate_random_string(self, stop_probability: float = 0.3) -> str:
|
||||
def generate_random_string(
|
||||
self, stop_probability: float = 0.3
|
||||
) -> tuple[str, list[str]]:
|
||||
result = []
|
||||
current_state = self.initial_state
|
||||
path = [current_state]
|
||||
|
||||
while True:
|
||||
if (
|
||||
@@ -59,5 +62,6 @@ class FiniteAutomaton:
|
||||
char = random.choice(transition)
|
||||
result.append(char)
|
||||
current_state = next_state
|
||||
path.append(current_state)
|
||||
|
||||
return "".join(result)
|
||||
return "".join(result), path
|
||||
|
||||
@@ -2,20 +2,22 @@ from finite_automaton import FiniteAutomaton
|
||||
|
||||
|
||||
def main():
|
||||
alphabet = set("+-0123456789.,eE")
|
||||
alphabet = set("+-0123456789.eE")
|
||||
initial_state = "S0"
|
||||
final_states = {"S2", "S4", "S7", "S8", "S9"}
|
||||
final_states = {"S2", "S3", "S5", "S7", "S10"}
|
||||
|
||||
transitions = {
|
||||
"S0": [("+-", "S1"), ("123456789", "S2"), ("0", "S8")],
|
||||
"S1": [("123456789", "S2"), ("0", "S8")],
|
||||
"S2": [("0123456789", "S2"), (".,", "S3"), ("eE", "S5")],
|
||||
"S3": [("0123456789", "S4")],
|
||||
"S4": [("0123456789", "S4"), ("eE", "S5")],
|
||||
"S5": [("+-", "S6"), ("123456789", "S7"), ("0", "S9")],
|
||||
"S6": [("123456789", "S7"), ("0", "S9")],
|
||||
"S7": [("0123456789", "S7")],
|
||||
"S8": [(".,", "S3")],
|
||||
"S0": [("+-", "S1"), ("123456789", "S2"), ("0", "S3"), (".", "S6")],
|
||||
"S1": [("123456789", "S2"), ("0", "S3"), (".", "S6")],
|
||||
"S2": [("0123456789", "S2"), (".", "S5"), ("eE", "S8")],
|
||||
"S3": [("0", "S3"), ("123456789", "S4"), (".", "S5"), ("eE", "S8")],
|
||||
"S4": [("0123456789", "S4"), (".", "S5"), ("eE", "S8")],
|
||||
"S5": [("0123456789", "S5"), ("eE", "S8")],
|
||||
"S6": [("0123456789", "S7")],
|
||||
"S7": [("0123456789", "S7"), ("eE", "S8")],
|
||||
"S8": [("+-", "S9"), ("0123456789", "S10")],
|
||||
"S9": [("0123456789", "S10")],
|
||||
"S10": [("0123456789", "S10")],
|
||||
}
|
||||
|
||||
automaton = FiniteAutomaton(
|
||||
@@ -71,8 +73,9 @@ def main():
|
||||
print(f"Ошибка: {e}")
|
||||
continue
|
||||
|
||||
random_string = automaton.generate_random_string(stop_prob)
|
||||
random_string, path = automaton.generate_random_string(stop_prob)
|
||||
print(f"Сгенерированная строка: {random_string}")
|
||||
print("Путь переходов:", " -> ".join(path))
|
||||
|
||||
else:
|
||||
print(f"Неизвестная команда: {cmd}")
|
||||
|
||||
156
lab2/report.tex
@@ -152,27 +152,27 @@
|
||||
|
||||
\textit{Вариант 15}. Соответствие вещественного числа разным форматам представления.
|
||||
|
||||
\newpage
|
||||
\section {Математическое описание}
|
||||
\subsection{Форматы представления вещественных чисел}
|
||||
|
||||
В данной лабораторной работе рассматриваются следующие форматы представления вещественных чисел.
|
||||
\begin{itemize}
|
||||
\item Целые числа, например: \texttt{''123''}, \texttt{''-456''}, \texttt{''0''}, в т. ч. \texttt{''+0''}, \texttt{''-0''}.
|
||||
\item Десятичные числа с двумя возможными разделителями (точка или запятая), например: \texttt{''123.456''}, \texttt{''-456,789''}.
|
||||
\item Экспоненциальная форма (буква E может быть как в верхнем, так и в нижнем регистре), например: \texttt{''1.23E4''}, \texttt{''-4,56e-7''}, \texttt{''7e8''}.
|
||||
\item Десятичные числа с разделителем точка, например: \texttt{''123.456''}, \texttt{''-456.789''}, \texttt{''.5''}.
|
||||
\item Экспоненциальная форма (буква E может быть как в верхнем, так и в нижнем регистре), например: \texttt{''1.23E4''}, \texttt{''-4.56e-7''}, \texttt{''7e8''}.
|
||||
\end{itemize}
|
||||
|
||||
Формальное определение синтаксиса предложенного формата вещественных чисел в БНФ нотации:
|
||||
\begin{verbatim}
|
||||
real ::= decimal | exponential
|
||||
decimal ::= integer [separator digit {digit}]
|
||||
integer ::= [sign] (nonzerodigit {digit} | "0")
|
||||
exponential ::= decimal ("e" | "E") integer
|
||||
sign ::= "+" | "-"
|
||||
nonzerodigit ::= "1" | "2" | ... | "9"
|
||||
digit ::= "0" | nonzerodigit
|
||||
separator ::= "." | ","
|
||||
real ::= [sign] (integer | float | exponentnumber)
|
||||
sign ::= "+" | "-"
|
||||
|
||||
integer ::= nonzerodigit {digit} | "0" {"0"}
|
||||
nonzerodigit ::= "1" | "2" | ... | "9"
|
||||
digit ::= "0" | nonzerodigit
|
||||
|
||||
float ::= {digit} "." digitpart | digitpart "."
|
||||
digitpart ::= digit {digit}
|
||||
|
||||
exponentnumber ::= (digitpart | float) exponent
|
||||
exponent ::= ("e" | "E") [sign] digitpart
|
||||
\end{verbatim}
|
||||
Где:
|
||||
\begin{itemize}
|
||||
@@ -182,7 +182,8 @@
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
\newpage
|
||||
\section {Математическое описание}
|
||||
\subsection{Языки и грамматики}
|
||||
Языком над конечным словарем $\Sigma$ называется произвольное множество конечных цепочек над этим словарем.
|
||||
|
||||
@@ -248,22 +249,30 @@
|
||||
|
||||
Для разных форматов представления вещественных чисел были построены следующие регулярные выражения в соответствии с определённой БНФ нотацией:
|
||||
\begin{itemize}
|
||||
\item Десятичные и целые числа: \\
|
||||
\texttt{[+-]?([1-9][0-9]*|0)([.,][0-9]+)?}
|
||||
\item Целые числа: \\
|
||||
\texttt{[+-]?(0+|[1-9][0-9]*)}
|
||||
\item Десятичные числа: \\
|
||||
\texttt{[+-]?([0-9]*\textbackslash.[0-9]+|[0-9]+\textbackslash.)}
|
||||
\item Экспоненциальная форма: \\
|
||||
\texttt{[+-]?([1-9][0-9]*|0)([.,][0-9]+)?[eE][+-]?([1-9][0-9]*|0)}
|
||||
\texttt{[+-]?([0-9]+|[0-9]*\textbackslash.[0-9]+|[0-9]+\textbackslash.)[eE][+-]?[0-9]+}
|
||||
\end{itemize}
|
||||
|
||||
Объединяя все форматы в соответствии с нашей БНФ нотацией, получаем следующее регулярное выражение, которое распознает все форматы вещественных чисел:
|
||||
|
||||
\texttt{[+-]?([1-9][0-9]*|0)([.,][0-9]+)?([eE][+-]?([1-9][0-9]*|0))?}
|
||||
|
||||
Объединяя, получаем следующее регулярное выражение, которое распознает все форматы вещественных чисел в соответствии с БНФ нотацией:
|
||||
\begin{verbatim}
|
||||
[+-]?(
|
||||
0+|
|
||||
[1-9][0-9]*|
|
||||
[0-9]*\.[0-9]+|
|
||||
[0-9]+\.|
|
||||
([0-9]+|[0-9]*\.[0-9]+|[0-9]+\.)[eE][+-]?[0-9]+
|
||||
)
|
||||
\end{verbatim}
|
||||
Разберём структуру этого выражения:
|
||||
\begin{itemize}
|
||||
\item \texttt{[+-]?} -- необязательный знак числа (плюс или минус)
|
||||
\item \texttt{([1-9][0-9]*|0)} -- целая часть числа, которая может быть либо нулём, либо цифрой от 1 до 9, за которой следует произвольное количество цифр
|
||||
\item \texttt{([.,][0-9]+)?} -- необязательная десятичная часть, состоящая из разделителя (точка или запятая) и как минимум одной цифры
|
||||
\item \texttt{([eE][+-]?([1-9][0-9]*|0))?} -- необязательная экспоненциальная часть, состоящая из буквы E (в любом регистре), необязательного знака и целого числа
|
||||
\item \texttt{0+|[1-9][0-9]*} -- целое число, которое может быть либо последовательностью нулей, либо цифрой от 1 до 9, за которой следует произвольное количество цифр.
|
||||
\item \texttt{[0-9]*\textbackslash.[0-9]+|[0-9]+\textbackslash.} -- десятичное число, которое может быть представлено произвольным количеством цифр до и как минимум одной цифрой после точки, либо произвольным количеством цифр и одной точкой в конце.
|
||||
\item \texttt{([0-9]+|[0-9]*\textbackslash.[0-9]+|[0-9]+\textbackslash.)[eE][+-]?[0-9]+} -- экспоненциальная форма числа, состоящая из произвольного количества цифр, либо десятичного числа, за которым следует буква E (в любом регистре), необязательный знак и как минимум одна цифра.
|
||||
\end{itemize}
|
||||
|
||||
Таким образом, полученное регулярное выражение распознаёт формат представления вещественных чисел, рассматриваемый в данной работе, и полностью соответствует формальному определению, представленному в БНФ нотации.
|
||||
@@ -335,27 +344,29 @@
|
||||
\footnotesize
|
||||
\begin{tabularx}{\textwidth}{|c|X|X|X|X|X|}
|
||||
\hline
|
||||
\textbf{Состояние\textbackslash Вход} & \textbf{+-} & \textbf{0} & \textbf{1-9} & \textbf{.,} & \textbf{eE} \\
|
||||
\textbf{Состояние\textbackslash Вход} & \textbf{+-} & \textbf{0} & \textbf{1-9} & \textbf{.} & \textbf{eE} \\
|
||||
\hline
|
||||
$S_0$ & $S_1$ & $S_8$ & $S_2$ & -- & -- \\
|
||||
$S_0$ & $S_1$ & $S_3$ & $S_2$ & $S_6$ & -- \\
|
||||
\hline
|
||||
$S_1$ & -- & $S_8$ & $S_2$ & -- & -- \\
|
||||
$S_1$ & -- & $S_3$ & $S_2$ & $S_6$ & -- \\
|
||||
\hline
|
||||
$S_2$ & -- & $S_2$ & $S_2$ & $S_3$ & $S_5$ \\
|
||||
$S_2$ & -- & $S_2$ & $S_2$ & $S_5$ & $S_8$ \\
|
||||
\hline
|
||||
$S_3$ & -- & $S_4$ & $S_4$ & -- & -- \\
|
||||
$S_3$ & -- & $S_3$ & $S_4$ & $S_5$ & $S_8$ \\
|
||||
\hline
|
||||
$S_4$ & -- & $S_4$ & $S_4$ & -- & $S_5$ \\
|
||||
$S_4$ & -- & $S_4$ & $S_4$ & $S_5$ & $S_8$ \\
|
||||
\hline
|
||||
$S_5$ & $S_6$ & $S_9$ & $S_7$ & -- & -- \\
|
||||
$S_5$ & -- & $S_5$ & $S_5$ & -- & $S_8$ \\
|
||||
\hline
|
||||
$S_6$ & -- & $S_9$ & $S_7$ & -- & -- \\
|
||||
$S_6$ & -- & $S_7$ & $S_7$ & -- & -- \\
|
||||
\hline
|
||||
$S_7$ & -- & -- & $S_7$ & -- & -- \\
|
||||
$S_7$ & -- & $S_7$ & $S_7$ & -- & $S_8$ \\
|
||||
\hline
|
||||
$S_8$ & -- & -- & -- & $S_3$ & -- \\
|
||||
$S_8$ & $S_9$ & $S_{10}$ & $S_{10}$ & -- & -- \\
|
||||
\hline
|
||||
$S_9$ & -- & -- & -- & -- & -- \\
|
||||
$S_9$ & -- & $S_{10}$ & $S_{10}$ & -- & -- \\
|
||||
\hline
|
||||
$S_{10}$ & -- & $S_{10}$ & $S_{10}$ & -- & -- \\
|
||||
\hline
|
||||
\end{tabularx}
|
||||
\label{tab:nka}
|
||||
@@ -374,7 +385,6 @@
|
||||
\label{fig:ka}
|
||||
\end{figure}
|
||||
|
||||
Матрица переходов для данного автомата представлена в Таблице~\ref{tab:ka}.
|
||||
|
||||
\begin{table}[h!]
|
||||
\centering
|
||||
@@ -382,35 +392,39 @@
|
||||
\footnotesize
|
||||
\begin{tabularx}{\textwidth}{|c|X|X|X|X|X|}
|
||||
\hline
|
||||
\textbf{Состояние\textbackslash Вход} & \textbf{+-} & \textbf{0} & \textbf{1-9} & \textbf{.,} & \textbf{eE} \\
|
||||
\textbf{Состояние\textbackslash Вход} & \textbf{+-} & \textbf{0} & \textbf{1-9} & \textbf{.} & \textbf{eE} \\
|
||||
\hline
|
||||
$S_0$ & $S_1$ & $S_8$ & $S_2$ & $S_E$ & $S_E$ \\
|
||||
$S_0$ & $S_1$ & $S_3$ & $S_2$ & $S_6$ & $S_E$ \\
|
||||
\hline
|
||||
$S_1$ & $S_E$ & $S_8$ & $S_2$ & $S_E$ & $S_E$ \\
|
||||
$S_1$ & $S_E$ & $S_3$ & $S_2$ & $S_6$ & $S_E$ \\
|
||||
\hline
|
||||
$S_2$ & $S_E$ & $S_2$ & $S_2$ & $S_3$ & $S_5$ \\
|
||||
$S_2$ & $S_E$ & $S_2$ & $S_2$ & $S_5$ & $S_8$ \\
|
||||
\hline
|
||||
$S_3$ & $S_E$ & $S_4$ & $S_4$ & $S_E$ & $S_E$ \\
|
||||
$S_3$ & $S_E$ & $S_3$ & $S_4$ & $S_5$ & $S_8$ \\
|
||||
\hline
|
||||
$S_4$ & $S_E$ & $S_4$ & $S_4$ & $S_E$ & $S_5$ \\
|
||||
$S_4$ & $S_E$ & $S_4$ & $S_4$ & $S_5$ & $S_8$ \\
|
||||
\hline
|
||||
$S_5$ & $S_6$ & $S_9$ & $S_7$ & $S_E$ & $S_E$ \\
|
||||
$S_5$ & $S_E$ & $S_5$ & $S_5$ & $S_E$ & $S_8$ \\
|
||||
\hline
|
||||
$S_6$ & $S_E$ & $S_9$ & $S_7$ & $S_E$ & $S_E$ \\
|
||||
$S_6$ & $S_E$ & $S_7$ & $S_7$ & $S_E$ & $S_E$ \\
|
||||
\hline
|
||||
$S_7$ & $S_E$ & $S_E$ & $S_7$ & $S_E$ & $S_E$ \\
|
||||
$S_7$ & $S_E$ & $S_7$ & $S_7$ & $S_E$ & $S_8$ \\
|
||||
\hline
|
||||
$S_8$ & $S_E$ & $S_E$ & $S_E$ & $S_3$ & $S_E$ \\
|
||||
$S_8$ & $S_9$ & $S_{10}$ & $S_{10}$ & $S_E$ & $S_E$ \\
|
||||
\hline
|
||||
$S_9$ & $S_E$ & $S_E$ & $S_E$ & $S_E$ & $S_E$ \\
|
||||
$S_9$ & $S_E$ & $S_{10}$ & $S_{10}$ & $S_E$ & $S_E$ \\
|
||||
\hline
|
||||
$S_{10}$ & $S_E$ & $S_{10}$ & $S_{10}$ & $S_E$ & $S_E$ \\
|
||||
\hline
|
||||
\end{tabularx}
|
||||
\label{tab:ka}
|
||||
\end{table}
|
||||
|
||||
|
||||
\newpage
|
||||
Матрица переходов для данного автомата представлена в Таблице~\ref{tab:ka}.
|
||||
|
||||
|
||||
\newpage
|
||||
\phantom{text}
|
||||
\newpage
|
||||
\section{Особенности реализации}
|
||||
\subsection{Общая структура программы}
|
||||
@@ -502,9 +516,12 @@ def process_input(self, input_string: str) -> tuple[str, list[str]]:
|
||||
\end{enumerate}
|
||||
|
||||
\begin{lstlisting}[caption={Код метода \texttt{generate\_random\_string}.}, label={lst:generate_random_string}]
|
||||
def generate_random_string(self, stop_probability: float = 0.3) -> str:
|
||||
def generate_random_string(
|
||||
self, stop_probability: float = 0.3
|
||||
) -> tuple[str, list[str]]:
|
||||
result = []
|
||||
current_state = self.initial_state
|
||||
path = [current_state]
|
||||
|
||||
while True:
|
||||
if (
|
||||
@@ -518,8 +535,9 @@ def generate_random_string(self, stop_probability: float = 0.3) -> str:
|
||||
char = random.choice(transition)
|
||||
result.append(char)
|
||||
current_state = next_state
|
||||
path.append(current_state)
|
||||
|
||||
return "".join(result)
|
||||
return "".join(result), path
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
@@ -537,20 +555,22 @@ def generate_random_string(self, stop_probability: float = 0.3) -> str:
|
||||
|
||||
\begin{lstlisting}[caption={Функция main.}, label={lst:Main}]
|
||||
def main():
|
||||
alphabet = set("+-0123456789.,eE")
|
||||
alphabet = set("+-0123456789.eE")
|
||||
initial_state = "S0"
|
||||
final_states = {"S2", "S4", "S7", "S8", "S9"}
|
||||
final_states = {"S2", "S3", "S5", "S7", "S10"}
|
||||
|
||||
transitions = {
|
||||
"S0": [("+-", "S1"), ("123456789", "S2"), ("0", "S8")],
|
||||
"S1": [("123456789", "S2"), ("0", "S8")],
|
||||
"S2": [("0123456789", "S2"), (".,", "S3"), ("eE", "S5")],
|
||||
"S3": [("0123456789", "S4")],
|
||||
"S4": [("0123456789", "S4"), ("eE", "S5")],
|
||||
"S5": [("+-", "S6"), ("123456789", "S7"), ("0", "S9")],
|
||||
"S6": [("123456789", "S7"), ("0", "S9")],
|
||||
"S7": [("0123456789", "S7")],
|
||||
"S8": [(".,", "S3")],
|
||||
"S0": [("+-", "S1"), ("123456789", "S2"), ("0", "S3"), (".", "S6")],
|
||||
"S1": [("123456789", "S2"), ("0", "S3"), (".", "S6")],
|
||||
"S2": [("0123456789", "S2"), (".", "S5"), ("eE", "S8")],
|
||||
"S3": [("0", "S3"), ("123456789", "S4"), (".", "S5"), ("eE", "S8")],
|
||||
"S4": [("0123456789", "S4"), (".", "S5"), ("eE", "S8")],
|
||||
"S5": [("0123456789", "S5"), ("eE", "S8")],
|
||||
"S6": [("0123456789", "S7")],
|
||||
"S7": [("0123456789", "S7"), ("eE", "S8")],
|
||||
"S8": [("+-", "S9"), ("0123456789", "S10")],
|
||||
"S9": [("0123456789", "S10")],
|
||||
"S10": [("0123456789", "S10")],
|
||||
}
|
||||
|
||||
automaton = FiniteAutomaton(
|
||||
@@ -606,8 +626,9 @@ def main():
|
||||
print(f"Ошибка: {e}")
|
||||
continue
|
||||
|
||||
random_string = automaton.generate_random_string(stop_prob)
|
||||
random_string, path = automaton.generate_random_string(stop_prob)
|
||||
print(f"Сгенерированная строка: {random_string}")
|
||||
print("Путь переходов:", " -> ".join(path))
|
||||
|
||||
else:
|
||||
print(f"Неизвестная команда: {cmd}")
|
||||
@@ -624,7 +645,7 @@ def main():
|
||||
\label{fig:result1}
|
||||
\end{figure}
|
||||
|
||||
На Рис.~\ref{fig:wrong} представлена реакция программы на некорректный пользовательский ввод.
|
||||
\newpage
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
@@ -633,11 +654,14 @@ def main():
|
||||
\label{fig:wrong}
|
||||
\end{figure}
|
||||
|
||||
На Рис.~\ref{fig:wrong} представлена реакция программы на некорректный пользовательский ввод.
|
||||
|
||||
|
||||
\newpage
|
||||
\section*{Заключение}
|
||||
\addcontentsline{toc}{section}{Заключение}
|
||||
В ходе выполнения лабораторной работы было построено регулярное выражение для распознавания различных форматов вещественных чисел, созданы недетерминированный и детерминированный конечные автоматы-распознаватели. На основе разработанного автомата была реализована программа, которая проверяет соответствие входной строки заданному формату и генерирует случайные корректные строки.
|
||||
В ходе выполнения лабораторной работы было построено регулярное выражение для распознавания различных форматов вещественных чисел. В соответствии с теоремой Клини по заданному регулярному выражению, задающему регулярный
|
||||
язык, был построен недетерминированный конечный автомат-распознаватель. Затем полученный конечный автомат был детерминирован. На основе разработанного автомата была реализована программа, которая проверяет соответствие входной строки заданному формату и генерирует случайные корректные строки.
|
||||
|
||||
Из достоинств выполнения лабораторной работы можно выделить структурирование кода за счёт использования ООП. Вся логика работы с конечными автоматами вынесена в отдельный класс \texttt{FiniteAutomaton} с четко разделенными методами для проверки строк и генерации случайных строк. Создана удобная интерактивная консольная оболочка для взаимодействия с пользователем, позволяющая выполнять различные команды.
|
||||
|
||||
|
||||