05c hw
This commit is contained in:
parent
3e095d010d
commit
c662ae1464
|
@ -700,9 +700,9 @@ cat0 equal to cat3? false
|
|||
|
||||
\subsection*{Практическое задание}
|
||||
\begin{enumerate}
|
||||
\item создать пару-тройку текстовых файлов. Для упрощения (не разбираться с кодировками) внутри файлов следует писать текст только латинскими буквами.
|
||||
\item написать метод, осуществляющий конкатенацию переданных ей в качестве параметров файлов (не особо важно, в первый допишется второй или во второй первый, или файлы вовсе объединятся в какой-то третий);
|
||||
\item написать метод поиска слова внутри файла.
|
||||
\item Cоздать пару-тройку текстовых файлов. Для упрощения (чтобы не разбираться с кодировками) внутри файлов следует писать текст только латинскими буквами.
|
||||
\item Написать метод, осуществляющий конкатенацию (объединение) переданных ей в качестве параметров файлов (не важно, в первый допишется второй или во второй первый, или файлы вовсе объединятся в какой-то третий);
|
||||
\item Написать метод поиска слова внутри файла.
|
||||
\end{enumerate}
|
||||
|
||||
\newpage
|
||||
|
|
Binary file not shown.
|
@ -2,7 +2,7 @@
|
|||
\usepackage{spreadtab}
|
||||
|
||||
\begin{document}
|
||||
\setcounter{section}{3}
|
||||
\setcounter{section}{4}
|
||||
\section{Семинар: обработка исключений}
|
||||
\subsection{Инструментарий}
|
||||
\begin{itemize}
|
||||
|
@ -73,29 +73,29 @@
|
|||
\end{itemize}
|
||||
\item \textbf{Вопросы и ответы:}
|
||||
\begin{enumerate}
|
||||
\item Перечисление -- это: 2
|
||||
\item Что такое GPT?
|
||||
\begin{enumerate}
|
||||
\item массив
|
||||
\item класс
|
||||
\item объект
|
||||
\item General partition trace;
|
||||
\item GUID partition table;
|
||||
\item Greater pass timing.
|
||||
\end{enumerate}
|
||||
\item Инкапсуляция с использованием внутренних классов: 2
|
||||
\item Строки в языке Java -- это:
|
||||
\begin{enumerate}
|
||||
\item остаётся неизменной
|
||||
\item увеличивается
|
||||
\item уменьшается
|
||||
\item классы;
|
||||
\item массивы;
|
||||
\item объекты.
|
||||
\end{enumerate}
|
||||
\item Обработчик исключений -- это объект, работающий 1
|
||||
\item Ссылка на местонахождение -- это:
|
||||
\begin{enumerate}
|
||||
\item в специальном потоке
|
||||
\item в специальном ресурсе
|
||||
\item в специальный момент
|
||||
\item URI;
|
||||
\item URL;
|
||||
\item URN.
|
||||
\end{enumerate}
|
||||
\item Стектрейс - это 2
|
||||
\item Возможно ли чтение совершенно случайного байта данных из потока, к которому подключен объект \code{BufferedInputStream}?
|
||||
\begin{enumerate}
|
||||
\item часть потока выполнения программы;
|
||||
\item часть объекта исключения;
|
||||
\item часть информации в окне отладчика.
|
||||
\item да;
|
||||
\item нет;
|
||||
\item да, если это поток в программу из локального файла.
|
||||
\end{enumerate}
|
||||
\end{enumerate}
|
||||
\end{itemize}
|
||||
|
@ -110,41 +110,150 @@
|
|||
\item возможно, по предварительному опросу, демонстрирует и разбирает вариант решения одного из студентов.
|
||||
\end{itemize}
|
||||
\item \textbf{Домашнее задание из лекции:}
|
||||
\begin{itemize}
|
||||
\item Напишите два наследника класса \code{Exception}: ошибка преобразования строки и ошибка преобразования столбца.
|
||||
\begin{itemize}
|
||||
\item Создать пару-тройку текстовых файлов. Для упрощения (чтобы не разбираться с кодировками) внутри файлов следует писать текст только латинскими буквами.
|
||||
|
||||
\textbf{Вариант решения}
|
||||
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={Простые наследники}]
|
||||
private static final class ColumnMismatchException extends RuntimeException {
|
||||
ColumnMismatchException(String message) {
|
||||
super("Columns exception: " + message);
|
||||
}
|
||||
Задание не предполагало кода, но будет плюсом, если студенты создали файлы не вручную, а программным кодом. Для этого и последующих заданий понадобится набор констант и вспомогательный массив с названиями файлов
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
private static final Random rnd = new Random();
|
||||
private static final int CHAR_BOUND_L = 65;
|
||||
private static final int CHAR_BOUND_H = 90;
|
||||
private static final int FILES_AMOUNT = 10;
|
||||
private static final int WORDS_AMOUNT = 5;
|
||||
private static final int WORD_LENGTH = 10;
|
||||
private static final String WORD_TO_SEARCH = "geekbrains";
|
||||
|
||||
String[] fileNames = new String[FILES_AMOUNT];
|
||||
for (int i = 0; i < fileNames.length; i++)
|
||||
fileNames[i] = "file_" + i + ".txt";
|
||||
\end{lstlisting}
|
||||
|
||||
Файл записывается простым выходным потоком, в который (в приведённом ниже примере) записывается строка, сгенерированная методом. Из строки выделяется массив байтов методом \code{getBytes()}.
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
private static String generateSymbols(int amount) {
|
||||
StringBuilder sequence = new StringBuilder();
|
||||
for (int i = 0; i < amount; i++)
|
||||
sequence.append((char) (CHAR_BOUND_L + rnd.nextInt(CHAR_BOUND_H - CHAR_BOUND_L)));
|
||||
return sequence.toString();
|
||||
}
|
||||
|
||||
private static final class NumberIsNotNumberException extends RuntimeException {
|
||||
NumberIsNotNumberException(String message) {
|
||||
super("Not a number found: " + message);
|
||||
}
|
||||
private static void writeFileContents(String fileName, int length) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(fileName);
|
||||
fos.write(generateSymbols(length).getBytes());
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
\end{lstlisting}
|
||||
\end{lstlisting}
|
||||
|
||||
\item Разработайте исключения-наследники так, чтобы они информировали пользователя в формате ожидание/реальность.
|
||||
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={Составное сообщение}]
|
||||
private static final class RowMismatchException extends RuntimeException {
|
||||
RowMismatchException(int expected, int current, String value) {
|
||||
super(String.format("Rows exception: expected %d rows. Received %d rows in '%s' string",
|
||||
expected, current, value));
|
||||
}
|
||||
Вызов методов обёрнут в \code{try...catch} и формирует сразу файлы как для второго задания (конкатенации), так и третьего (поиска).
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
try {
|
||||
//#1
|
||||
for (int i = 0; i < fileNames.length; i++)
|
||||
if (i < 2)
|
||||
writeFileContents(fileNames[i], 100);
|
||||
else
|
||||
writeFileContents(fileNames[i], WORDS_AMOUNT, WORD_LENGTH);
|
||||
System.out.println("First task results are in file_0 and file_1.");
|
||||
}
|
||||
\end{lstlisting}
|
||||
catch (Exception ex) { throw new RuntimeException(ex); }
|
||||
\end{lstlisting}
|
||||
|
||||
\item для проверки напишите программу, преобразующую квадратный массив целых чисел 5х5 в сумму чисел в этом массиве, при этом, программа должна выбросить исключение, если строк или столбцов в исходном массиве окажется не 5.
|
||||
|
||||
\textbf{Вариант решения представлен в приложении \ref{appendix:hw3}}
|
||||
\item Написать метод, осуществляющий конкатенацию (соединение) переданных ей в качестве параметров файлов (не особенно важно, в первый допишется второй или во второй первый, или файлы вовсе объединятся в какой-то третий);
|
||||
|
||||
\end{itemize}
|
||||
\textbf{Вариант решения}
|
||||
|
||||
Метод конкатенации моет также быть написан множеством способов, но важно, чтобы при буферизации (чаще всего решения содержат именно буферизованные варианты) не терялись символы, например, пробелы или переходы на новую строку. Также часто встречается дополнительная буферизация внутри программы, например, в строку, при помощи \code{StringBuilder}, что будет являться грубой ошибкой при конкатенации больших или бинарных файлов. Поэтому ниже представлен вариант решения с посимвольным чтением и записью в результирующий файл.
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
private static void concatenate(String file_in1, String file_in2, String file_out) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(file_out);
|
||||
int ch;
|
||||
FileInputStream fis = new FileInputStream(file_in1);
|
||||
while ((ch = fis.read()) != -1)
|
||||
fos.write(ch);
|
||||
fis.close();
|
||||
|
||||
fis = new FileInputStream(file_in2);
|
||||
while ((ch = fis.read()) != -1)
|
||||
fos.write(ch);
|
||||
fis.close();
|
||||
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Вызов метода можно записать в секцию \code{try...catch} предыдущего задания или написать новую.
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
try {
|
||||
//#2
|
||||
concatenate(fileNames[0], fileNames[1], "FILE_OUT.txt");
|
||||
System.out.println("Second task result is in FILE_OUT.");
|
||||
}
|
||||
catch (Exception ex) { throw new RuntimeException(ex); }
|
||||
\end{lstlisting}
|
||||
|
||||
\item Написать метод поиска слова внутри файла.
|
||||
|
||||
\textbf{Вариант решения}
|
||||
|
||||
Для поиска слова понадобится файл не со сплошными символами (хотя и в таком алгоритм поиска должен отработать нормально), а со словами, разделёнными пробелами. Для этого можно видоизменить метод генерации файла и написать перегруженный, который будет по некоторому псевдослучайному условию вставлять в файл через пробел либо случайно сгенерированную последовательность символов, либо слово, заранее определённое, как искомое.
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
private static void writeFileContents(String fileName, int words, int length) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(fileName);
|
||||
for (int i = 0; i < words; i++) {
|
||||
if(rnd.nextInt(WORDS_AMOUNT) == WORDS_AMOUNT / 2)
|
||||
fos.write(WORD_TO_SEARCH.getBytes());
|
||||
else
|
||||
fos.write(generateSymbols(length).getBytes());
|
||||
fos.write(' ');
|
||||
}
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Формально, можно выполнить работу следующим образом, используя \code{Scanner}, сравнивая слова «от пробела до пробела»
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
private static boolean fileScanner(String fileName, String word) throws IOException {
|
||||
Scanner sc = new Scanner(new FileInputStream(fileName));
|
||||
word = word.toLowerCase(); // \n
|
||||
while (sc.hasNext()) {
|
||||
String line = sc.nextLine();
|
||||
line = line.toLowerCase();
|
||||
if (line.contains(word)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Но более гибким получится алгоритм, ищущий непосредственно последовательность символов, сравнивая их по одному, это позволяет искать не только словосочетания, но и, например, диалоги персонажей в книге.
|
||||
\begin{lstlisting}[language=Java,style=JCodeStyle,label={},caption={}]
|
||||
private static boolean isInFile(String fileName, String search) throws IOException {
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
byte[] searchSequence = search.getBytes();
|
||||
int ch;
|
||||
int i = 0; // geekgeekbrains
|
||||
while ((ch = fis.read()) != -1) {
|
||||
if (ch == searchSequence[i])
|
||||
i++;
|
||||
else {
|
||||
i = 0;
|
||||
if (ch == searchSequence[i]) i++;
|
||||
}
|
||||
if (i == searchSequence.length) {
|
||||
fis.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
fis.close();
|
||||
return false;
|
||||
}
|
||||
\end{lstlisting}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Вопросы и ответы}
|
||||
|
|
Loading…
Reference in New Issue