Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Готовые отчеты (2020) / Java. Лабораторная работа 4

.pdf
Скачиваний:
57
Добавлен:
29.01.2021
Размер:
540.96 Кб
Скачать

Федеральное агентство связи ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ

ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М. А. БОНЧ-БРУЕВИЧА» (СПбГУТ)

Факультет инфокоммуникационных сетей и систем Кафедра программной инженерии и вычислительной техники

ЛАБОРАТОРНАЯ РАБОТА №4

по дисциплине «Разработка Java-приложений управления телекоммуникациями»

Выполнил: студент 3-го курса дневного отделения группы ИКПИ-85

Коваленко Леонид Александрович Преподаватель:

доцент кафедры ПИиВТ Белая Татьяна Иоанновна

Санкт-Петербург

2020

Цель работы Ознакомиться с механизмом систем ввода и вывода данных.

Ход работы

Задание №1.

Создадим циклический двусвязный список CircularLinkedList с выделенной головой (т. е. голова не хранит значение, а «пустой» список состоит из одной головы, замкнутой на себя), в котором будут реализованы следующие методы:

конструктор с параметром n — числом элементов;

метод добавления элемента;

метод удаления элемента;

методы получения и изменения значения элемента списка по

индексу.

Также реализуем оптимизацию скорости доступа: внутри экземпляра списка будет храниться ссылка-узел и его номер, к которому производилось предыдущее обращение, а методы доступа (методы получения и изменения значения) к узлу по его номеру (а также методы добавления и удаления) должны двигаться к заданному узлу от ближайшего элемента: от предыдущего узла, от головы вперед, от головы назад (от хвоста).

Кроме того, создадим файл CircularLinkedListTest.java для проверки работы класса CircularLinkedList. Коды этих двух файлов приведены в табл. 1, 2.

Таблица 1 — Код vectors/CircularLinkedList.java package vectors;

public class CircularLinkedList implements IVector { // Конструктор

public CircularLinkedList(int n) {

current = head = new Node(0, null, null); head.prev = head.next = head; current_index = -1;

if (n > 0) {

Node temp = head;

for (int i = 0; i < n; ++i) {

temp = (temp.next = new Node(0, temp, null));

}

temp.next = head; head.prev = temp; size = n;

} else {

2

size = 0;

}

}

// Получение элемента по индексу

public double get(int i) throws VectorIndexOutOfBoundsException { if (i >= 0 && i < size) {

if (Math.abs(i - current_index) > Math.min(i + 1, size - i)) { current = head;

current_index = (i + i < size) ? -1 : size;

}

for (; current_index < i; ++current_index) { current = current.next;

}

for (; current_index > i; --current_index) { current = current.prev;

}

return current.value;

}

throw new VectorIndexOutOfBoundsException("VectorIndexOutOfBoundsException", i);

}

// Изменение значения элемента по индексу public void set(int i, double value) throws

VectorIndexOutOfBoundsException { if (i >= 0 && i < size) {

if (Math.abs(i - current_index) > Math.min(i + 1, size - i)) { current = head;

current_index = (i + i < size) ? -1 : size;

}

for (; current_index < i; ++current_index) { current = current.next;

}

for (; current_index > i; --current_index) { current = current.prev;

}

current.value = value; return;

}

throw new VectorIndexOutOfBoundsException("VectorIndexOutOfBoundsException", i);

}

//Получение длины списка public int size() {

return size;

}

//Добавление элемента в список

public void add(int i, double elem) throws VectorIndexOutOfBoundsException {

if (i >= 0 && i <= size) {

if (Math.abs(i - current_index) > Math.min(i + 1, size - i)) { current = head;

current_index = (i + i < size) ? -1 : size;

}

for (; current_index < i; ++current_index) { current = current.next;

}

for (; current_index > i; --current_index) { current = current.prev;

}

current = current.prev;

current.next = new Node(elem, current, current.next);

3

current.next.next.prev = current.next; current = current.next;

++size; return;

}

throw new VectorIndexOutOfBoundsException("VectorIndexOutOfBoundsException", i);

}

// Удаление элемента из списка

public void remove(int i) throws VectorIndexOutOfBoundsException { if (i >= 0 && i < size) {

if (Math.abs(i - current_index) > Math.min(i + 1, size - i)) { current = head;

current_index = (i + i < size) ? -1 : size;

}

for (; current_index < i; ++current_index) { current = current.next;

}

for (; current_index > i; --current_index) { current = current.prev;

}

current = current.prev; current.next = current.next.next; current.next.prev = current; current = current.next;

--size; return;

}

throw new VectorIndexOutOfBoundsException("VectorIndexOutOfBoundsException", i);

}

//Нахождение нормы Евклида public double normEuclidean() {

double r = 0;

for (Node temp = head.next; temp != head; temp = temp.next) { r += temp.value * temp.value;

}

return Math.sqrt(r);

}

//Вывод всех элементов списка

public void print() { Node temp = head.next; if (temp != head) {

System.out.print(temp.value); temp = temp.next;

}

for (; temp != head; temp = temp.next) { System.out.print(" " + temp.value);

}

System.out.println();

}

// Вывод всех элементов списка в обратном порядке public void rprint() {

Node temp = head.prev; if (temp != head) {

System.out.print(temp.value); temp = temp.prev;

}

for (; temp != head; temp = temp.prev) { System.out.print(" " + temp.value);

}

4

System.out.println();

}

// Класс "Узел"

public static class Node {

public Node(double value, Node prev, Node next) { this.value = value;

this.prev = prev; this.next = next;

}

public double value; public Node prev, next;

}

private Node head, current; private int size, current_index;

}

Таблица 2 — Код CircularLinkedListTest.java

import vectors.CircularLinkedList;

import vectors.VectorIndexOutOfBoundsException;

public class CircularLinkedListTest {

public static void main(String[] args) throws VectorIndexOutOfBoundsException {

CircularLinkedList list = new CircularLinkedList(10); System.out.print("Source list (10 elements): "); list.print();

System.out.println("\nMethod \'set\'. list.set(0, 1) and list.set(list.size() - 1, 10)");

list.set(0, 1); list.set(list.size() - 1, 10); System.out.print("New list: "); list.print();

System.out.print("Reversed new list: "); list.rprint(); System.out.println("\nMethod \'get\'.");

System.out.println("list.get(0): " + list.get(0)); System.out.println("list.get(list.size() - 1): " +

list.get(list.size() - 1));

System.out.print("\nMethod \'set\'. Ordered list: "); for (int i = 0, len = list.size(); i < len; ++i) {

list.set(i, i);

}

list.print();

System.out.print("Reverse ordered list: "); list.rprint();

System.out.print("Test of method \'get\': "); boolean flag = true;

for (int i = 0, len = list.size(); i < 10000000; ++i) { int k = (int) Math.random() * len;

if (list.get(k) != k) { flag = false; break;

}

}

System.out.println(flag ? "it works" : "this does not work"); System.out.println("\nMethod \'add\'."); System.out.println("list.add(0, -1) and list.add(list.size(), 10)"); list.add(0, -1);

list.add(list.size(), 10); System.out.print("List: "); list.print();

5

System.out.print("Reversed list: "); list.rprint();

System.out.println("list.normEuclidean(): " + list.normEuclidean()); CircularLinkedList newList = new CircularLinkedList(0); newList.add(0, 1);

newList.add(1, 2); newList.add(2, 3); newList.add(3, 4);

System.out.print("\nList[1, 2, 3, 4]: "); newList.print();

newList.remove(3);

newList.remove(2);

newList.remove(1);

newList.remove(0);

System.out.print("After removing all items:"); newList.print();

newList = new CircularLinkedList(0); newList.add(0, 1);

newList.add(0, 2); newList.add(0, 3); newList.add(0, 4);

System.out.print("List[4, 3, 2, 1]: "); newList.print();

newList.remove(0);

newList.remove(0);

newList.remove(0);

newList.remove(0);

System.out.print("After removing all items:"); newList.print();

}

}

Результат компиляции и запуска приведен на рис. 1.

Рисунок 1 — Компиляция и запуск CircularLinkedListTest.java

Задание №2.

Модифицируем класс Vectors из предыдущей работы, добавив в него следующие методы (табл. 3):

6

— метод записи вектора в байтовый поток: public static void

outputVector(Vector v, OutputStream out);

— метод чтения вектора из байтового потока: public static Vector

inputVector(InputStream in);

— метод записи вектора в символьный поток: public static void

writeVector(Vector v, Writer out);

— метод чтения вектора из символьного потока: public static Vector

readVector(Reader in).

Вобоих случаях записанный вектор будет представлять собой последовательность чисел, первым из которых является размерность вектора (тип int), а остальные являются значениями координат (тип double).

Вслучае символьного потока будем считать, что вектор записывается в одну строку, в которой числа разделены пробелами. Для чтения вектора из символьного потока будем использовать класс StreamTokenizer.

Также опишем класс VectorStreamTest (табл. 4), находящийся вне пакета vectors, содержащий точку входа программы — метод main(), в котором

проверим возможности методов записи и методов чтения. Таблица 3 — Измененный код vectors/Vectors.java

package vectors;

import java.io.IOException; import java.io.Writer; import java.io.Reader; import java.io.InputStream; import java.io.OutputStream;

import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.PrintWriter; import java.io.StreamTokenizer;

public class Vectors {

// Умножение вектора на число

public static IVector mul(IVector array, double number) { int size = array.size();

IVector r = new Array(size); try {

for (int i = 0; i < size; ++i) { r.set(i, array.get(i) * number);

}

}

catch(Exception e) { System.out.println(e.getMessage());

}

return r;

}

7

// Сложение двух векторов

public static IVector sum(IVector array, IVector arg) throws IncompatibleVectorSizesException {

int size = array.size(); if (size != arg.size()) {

throw new IncompatibleVectorSizesException("IncompatibleVectorSizesException", array.size(), arg.size());

}

IVector r = new Array(size); try{

for (int i = 0; i < size; ++i) { r.set(i, array.get(i) + arg.get(i));

}

}

catch(Exception e) { System.out.println(e.getMessage());

}

return r;

}

// Скалярное произведение двух векторов

public static double mul(IVector array, IVector arg) throws IncompatibleVectorSizesException {

int size = array.size(); if (size != arg.size()) {

throw new IncompatibleVectorSizesException("IncompatibleVectorSizesException", array.size(), arg.size());

}

double r = 0; try {

for (int i = 0; i < size; ++i) {

r += array.get(i) * arg.get(i);

}

}

catch(Exception e) { System.out.println(e.getMessage());

}

return r;

}

// Метод записи вектора в байтовый поток

public static void outputVector(IVector v, OutputStream out) throws IOException {

DataOutputStream dos = new DataOutputStream(out); int len = v.size();

dos.writeInt(len); try{

for (int i = 0; i < len; ++i) { dos.writeDouble(v.get(i));

}

}

catch(Exception e) { System.out.println(e.getMessage());

}

dos.flush();

}

// Метод чтения вектора из байтового потока

public static IVector inputVector(InputStream in) throws IOException { DataInputStream dis = new DataInputStream(in);

int len = dis.readInt(); IVector result = new Array(len);

8

try {

for (int i = 0; i < len; ++i) { result.set(i, dis.readDouble());

}

}

catch(Exception e) { System.out.println(e.getMessage());

}

return result;

}

// Метод записи вектора в символьный поток

public static void writeVector(IVector v, Writer out) throws IOException

{

PrintWriter pw = new PrintWriter(out); int len = v.size();

pw.print(len); try{

for (int i = 0; i < len; ++i) { pw.print(' '); pw.print(v.get(i));

}

}

catch(Exception e) { System.out.println(e.getMessage());

}

pw.flush();

}

// Метод чтения вектора из символьного потока

public static IVector readVector(Reader in) throws IOException { StreamTokenizer token = new StreamTokenizer(in);

int t = token.nextToken();

IVector v = new Array((t != StreamTokenizer.TT_EOF) ? (int) token.nval : 0);

t = token.nextToken(); try {

for (int i = 0; t != StreamTokenizer.TT_EOF; ++i, t = token.nextToken()) {

if (t == StreamTokenizer.TT_NUMBER) { v.set(i, token.nval);

}

}

}

catch(Exception e) { System.out.println(e.getMessage());

}

return v;

}

}

Таблица 4 — Код VectorStreamTest.java

import vectors.Array; import vectors.Vectors;

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.CharArrayReader; import java.io.CharArrayWriter;

public class VectorStreamTest {

public static void main(String[] args) throws Exception { Array arr = new Array(8);

for (int i = 0, len = arr.size(); i < len; ++i) { arr.set(i, i);

9

}

System.out.println("Work with byte streams"); System.out.print("Source array: "); arr.print();

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

Vectors.outputVector(arr, byteArrayOutputStream); byteArrayOutputStream.flush(); System.out.print("Internal data (in bytes): "); System.out.println(byteArrayOutputStream.toString()); ByteArrayInputStream byteArrayInputStream = new

ByteArrayInputStream(byteArrayOutputStream.toByteArray()); System.out.print("Received array: "); Vectors.inputVector(byteArrayInputStream).print();

System.out.println("\nWork with character streams"); System.out.print("Source array: ");

arr.print();

CharArrayWriter charArrayWriter = new CharArrayWriter(); Vectors.writeVector(arr, charArrayWriter); charArrayWriter.flush();

System.out.print("Internal data (in chars): "); System.out.println(charArrayWriter.toString()); CharArrayReader charArrayReader = new

CharArrayReader(charArrayWriter.toCharArray());

System.out.print("Received array: "); Vectors.readVector(charArrayReader).print();

}

}

Результат компиляции и запуска приведен на рис. 2.

Рисунок 2 — Компиляция и запуск VectorStreamTest.java Задание №3.

Модифицируем классы Array и CircularLinkedList таким образом, чтобы они были сериализуемыми (табл. 5, 6).

Таблица 5 — Измененный код vectors/Array.java

package vectors;

import java.io.Serializable;

public class Array implements IVector, Serializable {

//Конструктор public Array(int n) {

data = new double[n];

}

//Получение элемента по индексу

10