Правки по lab2

This commit is contained in:
2025-04-28 22:57:53 +03:00
parent 7030059bbb
commit 3963d304ec
7 changed files with 115 additions and 84 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -27,25 +27,28 @@ class FiniteAutomaton:
for char in input_string: for char in input_string:
if char not in self.alphabet: 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) next_state = self._get_next_state(current_state, char)
if next_state is None: if next_state is None:
return "Строка не соответствует", transitions_path return "Строка не соответствует", transitions_path
transitions_path.append(next_state) transitions_path.append(next_state)
current_state = next_state current_state = next_state
return ( return (
"Строка соответствует" "Строка соответствует"
if current_state in self.final_states if current_state in self.final_states
else "Строка не соответствует" else "Строка не соответствует"
), transitions_path ), 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 = [] result = []
current_state = self.initial_state current_state = self.initial_state
path = [current_state]
while True: while True:
if ( if (
@@ -59,5 +62,6 @@ class FiniteAutomaton:
char = random.choice(transition) char = random.choice(transition)
result.append(char) result.append(char)
current_state = next_state current_state = next_state
path.append(current_state)
return "".join(result) return "".join(result), path

View File

@@ -2,20 +2,22 @@ from finite_automaton import FiniteAutomaton
def main(): def main():
alphabet = set("+-0123456789.,eE") alphabet = set("+-0123456789.eE")
initial_state = "S0" initial_state = "S0"
final_states = {"S2", "S4", "S7", "S8", "S9"} final_states = {"S2", "S3", "S5", "S7", "S10"}
transitions = { transitions = {
"S0": [("+-", "S1"), ("123456789", "S2"), ("0", "S8")], "S0": [("+-", "S1"), ("123456789", "S2"), ("0", "S3"), (".", "S6")],
"S1": [("123456789", "S2"), ("0", "S8")], "S1": [("123456789", "S2"), ("0", "S3"), (".", "S6")],
"S2": [("0123456789", "S2"), (".,", "S3"), ("eE", "S5")], "S2": [("0123456789", "S2"), (".", "S5"), ("eE", "S8")],
"S3": [("0123456789", "S4")], "S3": [("0", "S3"), ("123456789", "S4"), (".", "S5"), ("eE", "S8")],
"S4": [("0123456789", "S4"), ("eE", "S5")], "S4": [("0123456789", "S4"), (".", "S5"), ("eE", "S8")],
"S5": [("+-", "S6"), ("123456789", "S7"), ("0", "S9")], "S5": [("0123456789", "S5"), ("eE", "S8")],
"S6": [("123456789", "S7"), ("0", "S9")], "S6": [("0123456789", "S7")],
"S7": [("0123456789", "S7")], "S7": [("0123456789", "S7"), ("eE", "S8")],
"S8": [(".,", "S3")], "S8": [("+-", "S9"), ("0123456789", "S10")],
"S9": [("0123456789", "S10")],
"S10": [("0123456789", "S10")],
} }
automaton = FiniteAutomaton( automaton = FiniteAutomaton(
@@ -71,8 +73,9 @@ def main():
print(f"Ошибка: {e}") print(f"Ошибка: {e}")
continue continue
random_string = automaton.generate_random_string(stop_prob) random_string, path = automaton.generate_random_string(stop_prob)
print(f"Сгенерированная строка: {random_string}") print(f"Сгенерированная строка: {random_string}")
print("Путь переходов:", " -> ".join(path))
else: else:
print(f"Неизвестная команда: {cmd}") print(f"Неизвестная команда: {cmd}")

View File

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