Правки по 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

View File

@@ -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} с четко разделенными методами для проверки строк и генерации случайных строк. Создана удобная интерактивная консольная оболочка для взаимодействия с пользователем, позволяющая выполнять различные команды.