Національний технічний університет України
«Київський політехнічний інститут імені Ігоря Сікорського»
Алгоритмізація та програмування 2: Процедурне програмування
ЗВІТ
до лабораторної роботи №4
«Списки»
(ТЕМА)
Варіант № 7
Дата «31» травня 2022
Завдання
1. Дослідити особливості створення одно- та дво-направлених списків.
2. Вивчити і реалізувати механізми додавання нових записів у список, пошуку записів у списку за певними полями, видалення записів зі списку та редагування знайдених записів, а також збереження всього списку у файлі та зчитування списку із файлу до пам’яті з відновленням всіх зв’язків.
3. Розробити Блок-схему програмного алгоритму.
4. Оформити ЗВІТ до лабораторної роботи згідно вимог та методичних рекомендацій.
Результат роботи
1. Роздрукувати (вивести на екран) попередньо сформовані та підготовлені для запису в файл дані.
2. Роздрукувати (вивести на екран) результат виконання операції читання даних із файлу.
3. ЗВІТ до комп’ютерного практикуму для перевірки додати в Клас.
4. Програмний код (відкритий для редагування) розмістити на сайті Repl.it (посилання виключно через кнопку «+Invite »).
Теоретичні відомості та опис роботи алгоритму
Пов’язаний список – це спосіб зберігання колекції елементів. Як і масив, вони можуть бути символами або цілими числами. Кожен елемент у зв'язаному списку зберігається у вигляді вузла .
Вузол:
/
Вузол — це сукупність двох піделементів або частин. Частина data , яка зберігає елемент, і next частина, яка зберігає посилання на наступний вузол.
Пов'язаний список:
/
Зв’язаний список утворюється, коли багато таких вузлів з’єднуються разом, утворюючи ланцюг. Кожен вузол вказує на наступний вузол, присутній у порядку. Перший вузол завжди використовується як посилання для обходу списку і називається HEAD . Останній вузол вказує на NULL .
Оголошення зв’язаного списку :
У мові C зв’язаний список можна реалізувати за допомогою структури та покажчиків.
struct LinkedList{
int data;
struct LinkedList *next;
};
Наведене вище визначення використовується для створення кожного вузла в списку. Поле data зберігає елемент, а next — це покажчик для зберігання адреси наступного вузла.
При запуску створеної програми користувач має обрати або створення списку за допомогою зчитування з файлу, або вводячи кожного студента власноруч. Якщо обрано перший варіант, то використовується метод readFromFile, який зчитую інформацію з файлу student.txt та створює список зі всіма зв’язками та полями. Якщо обрано другий варіант, то користувач має ввести кількість студентів та ввести інформацію про кожного. Ці дані використовуються для методу addNode, який додає елемент до списку.
Далі користувач доходе до стандартного меню з вибором функції для виконання. Він може вивести список на екран, додати новий елемент до списку, видалити елемент, редагувати записи, шукати інформацію за конкретним полем серед всіх студентів та зберігати створений список до файлу для подальшого використання. Меню реалізовано за допомогою нескінченного циклу while, а кінець програми буде, якщо обрати в меню “кінець роботи”.
Результат програми
Створення нового списку власноруч
/
/
Зчитування списку за файлу
/
1)Додавання нового елемента
/
/
2)Видалення
/
3)Редагування записів
/
4)Пошук записів
/
5)Збереження списку до файлу
/
Висновок: було досліджено особливості створення одно-направлених списків. Створено список такого виду зі всіма необхідними функціями, такими як: вивід списку на екран, додавання нових елементів, видалення елементів, редагування записів, пошук записів, збереження списку до файлу, зчитування списку з файлу.
Посилання на repl.it: https://replit.com/join/uvaanfddhh-vladsosiedskii
Код програми
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define RED "\x1b[31m"
#define BLUE "\x1b[34m"
#define WHITE "\x1b[0m"
using namespace std;
struct Node {
int number;
string name;
string surname;
string patronymic;
string homeAddress;
string group;
double rating;
Node *next;
};
class List {
private:
Node *head;
Node *last;
public:
List()
{
head = NULL;
}
void addNode(int newNumber, string newName, string newSurname,
string newPatronymic, string newHomeAddress, string newGroup,
double newRating) {
Node *nd = new Node;
nd->number = newNumber;
nd->name = newName;
nd->surname = newSurname;
nd->patronymic = newPatronymic;
nd->homeAddress = newHomeAddress;
nd->group = newGroup;
nd->rating = newRating;
nd->next = NULL;
if (head == NULL)
head = nd;
else
{
Node *current = head;
while (current->next != NULL)
current = current->next;
current->next = nd;
}
}
void remove(int numDelete) {
int count = 0;
Node *temp = head, *helping = head;
for (int i = 0; i < numDelete; i++) {
helping = temp;
temp = temp->next;
}
if (temp == head)
{
head = temp->next;
} else {
helping->next = temp->next;
}
free(temp);
}
void printList() {
Node *current = head;
while (current != NULL) {
cout << "\nСтудент: " << current->number << endl;
cout << "Ім'я: " << current->name << endl;
cout << "Прізвище: " << current->surname << endl;
cout << "По батькові: " << current->patronymic << endl;
cout << "Домашня адреса: " << current->homeAddress << endl;
cout << "Група: " << current->group << endl;
cout << "Рейтинг: " << current->rating << endl << endl;
current = current->next;
}
}
void findElement(int element) {
Node *current = head;
while (current != NULL) {
cout << "Студент " << current->number << endl;
switch (element) {
case 1:
cout << "Ім'я " << current->name << endl << endl;
break;
case 2:
cout << "Прізвище " << current->surname << endl << endl;
break;
case 3:
cout << "По батькові " << current->patronymic << endl << endl;
break;
case 4:
cout << "Домашня адреса " << current->homeAddress << endl << endl;
break;
case 5:
cout << "Група " << current->group << endl << endl;
break;
case 6:
cout << "Рейтинг " << current->rating << endl << endl;
break;
}
current = current->next;
}
}
void changeElement(int student, int element) {
Node *current = head;
for (int i = 0; i < student; i++) {
current = current->next;
}
switch (element) {
case 0:
cout << "Студент: ";
cin >> current->number;
break;
case 1:
cout << "Ім'я: ";
cin >> current->name;
break;
case 2:
cout << "Прізвище: ";
cin >> current->surname;
break;
case 3:
cout << "По батькові: ";
cin >> current->patronymic;
break;
case 4:
cout << "Домашня адреса: ";
cin >> current->homeAddress;
break;
case 5:
cout << "Група: ";
cin >> current->group;
break;
case 6:
cout << "Рейтинг: ";
cin >> current->rating;
break;
}
}
void saveToFile() {
ofstream student("student.txt");
Node *current = head;
while (current != NULL) {
student << "Студент: " << current->number << endl;
student << "Ім'я: " << current->name << endl;
student << "Прізвище: " << current->surname << endl;
student << "По батькові: " << current->patronymic << endl;
student << "Домашня адреса: " << current->homeAddress << endl;
student << "Група: " << current->group << endl;
student << "Рейтинг: " << current->rating << endl << endl;
current = current->next;
}
student.close();
}
void readFromFile(int num) {
ifstream fileStudent("student.txt");
if (!fileStudent) {
cout << "Файл не відкрито";
exit(1);
}
int stringNumber = 0;
string number;
string name;
string surname;
string patronymic;
string homeAddress;
string group;
double rating;
while (fileStudent.good() && stringNumber < num) {
char c;
fileStudent.get(c);
for (int i = 0; c != ':' && fileStudent.good(); i++) {
fileStudent.get(c);
}
fileStudent.get(c);
getline(fileStudent, number);
for (int i = 0; c != ':' && fileStudent.good(); i++) {
fileStudent.get(c);
}
fileStudent.get(c);
getline(fileStudent, name);
for (int i = 0; c != ':' && fileStudent.good(); i++) {
fileStudent.get(c);
}
fileStudent.get(c);
getline(fileStudent, surname);
for (int i = 0; c != ':' && fileStudent.good(); i++) {
fileStudent.get(c);
}
fileStudent.get(c);
getline(fileStudent, patronymic);
for (int i = 0; c != ':' && fileStudent.good(); i++) {
fileStudent.get(c);
}
fileStudent.get(c);
getline(fileStudent, homeAddress);
for (int i = 0; c != ':' && fileStudent.good(); i++) {
fileStudent.get(c);
}
fileStudent.get(c);
getline(fileStudent, group);
for (int i = 0; c != ':' && fileStudent.good(); i++) {
fileStudent.get(c);
}
fileStudent.get(c);
string temp1;
getline(fileStudent, temp1);
rating = atof(temp1.c_str());
Node *nd = new Node;
nd->number = stoi(number);
nd->name = name;
nd->surname = surname;
nd->patronymic = patronymic;
nd->homeAddress = homeAddress;
nd->group = group;
nd->rating = rating;
nd->next = NULL;
if (head == NULL)
head = nd;
else
{
Node *current = head;
while (current->next != NULL)
current = current->next;
current->next = nd;
}
stringNumber++;
}
fileStudent.close();
}
};
int main() {
List newList;
int typeOfFill;
while (1) {
cout << "Оберіть спосіб створення списку:" << endl;
cout << BLUE "1" WHITE " - Зчитування з файлу" << endl;
cout << BLUE "2" WHITE " - Введення інформації" << endl;
cout << "Вибір: ";
cin >> typeOfFill;
if (typeOfFill != 1 && typeOfFill != 2) {
cout << "Введено невірне значення" << endl << endl;
continue;
} else
break;
}
int numberOfStudents;
if (typeOfFill == 1) {
cout << "\nВведіть кількість студентів: ";
cin >> numberOfStudents;
newList.readFromFile(numberOfStudents);
}
if (typeOfFill == 2) {
cout << "\nВведіть кількість студентів: ";
cin >> numberOfStudents;
int number;
string name;
string surname;
string patronymic;
string homeAddress;
string group;
double rating;
for (int i = 0; i < numberOfStudents; i++) {
cout << "\nСтудент номер " << i << endl;
number = i;
cout << "Введіть ім'я: ";
cin >> name;
cout << "Введіть прізвище: ";
cin >> surname;
cout << "Введіть по батькові: ";
cin >> patronymic;
cout << "Введіть домашню адресу: ";
cin.ignore(256, '\n');
getline(cin, homeAddress);
cout << "Введіть номер групи: ";
cin >> group;
cout << "Введіть рейтинг: ";
cin >> rating;
newList.addNode(number, name, surname, patronymic, homeAddress, group,
rating);
}
}
while (1) {
cout << "\nОберіть функцію:" << endl;
cout << BLUE"0" WHITE " - Вивід на екран списку" << endl;
cout << BLUE"1" WHITE " - Додавання нового запису до списку" << endl;
cout << BLUE"2" WHITE " - Видалення запису зі списку" << endl;
cout << BLUE"3" WHITE " - Редагування записів" << endl;
cout << BLUE"4" WHITE " - Пошук інформації" << endl;
cout << BLUE"5" WHITE " - Збереження списку до файлу" << endl;
cout << BLUE"6" WHITE " - Кінець роботи" << endl;
cout << "Вибір: ";
int task;
cin >> task;
if (task == 0) {
newList.printList();
}
if (task == 1) {
int number;
string name;
string surname;
string patronymic;
string homeAddress;
string group;
double rating;
cout << "\nВведіть номер: ";
cin >> number;
cout << "Введіть ім'я: ";
cin >> name;
cout << "Введіть прізвище: ";
cin >> surname;
cout << "Введіть по батькові: ";
cin >> patronymic;
cout << "Введіть домашню адресу: ";
cin.ignore(256, '\n');
getline(cin, homeAddress);
cout << "Введіть номер групи: ";
cin >> group;
cout << "Введіть рейтинг: ";
cin >> rating;
newList.addNode(number, name, surname, patronymic, homeAddress, group,
rating);
}
if (task == 2) {
int numDelete;
cout << "Введіть номер студента, для видалення: ";
cin >> numDelete;
newList.remove(numDelete);
}
if (task == 3) {
cout << "\nВведіть номер студента, поле якого буде змінено: ";
int studentChange;
cin >> studentChange;
cout << "Введіть номер поля, яке буде змінено:" << endl;
cout << BLUE"0" WHITE " - Cтудент" << endl;
cout << BLUE"1" WHITE " - Ім'я" << endl;
cout << BLUE"2" WHITE " - Прізвище" << endl;
cout << BLUE"3" WHITE " - По батькові" << endl;
cout << BLUE"4" WHITE " - Домашная адреса" << endl;
cout << BLUE"5" WHITE " - Група" << endl;
cout << BLUE"6" WHITE " - Рейтинг" << endl;
cout << "Вибір: ";
int elementChange;
cin >> elementChange;
cout << endl;
newList.changeElement(studentChange, elementChange);
}
if (task == 4) {
cout << "\nВведіть номер елемента для пошуку" << endl;
cout << BLUE"1" WHITE " - Ім'я" << endl;
cout << BLUE"2" WHITE " - Прізвище" << endl;
cout << BLUE"3" WHITE " - По батькові" << endl;
cout << BLUE"4" WHITE " - Домашная адреса" << endl;
cout << BLUE"5" WHITE " - Група" << endl;
cout << BLUE"6" WHITE " - Рейтинг" << endl;
cout << "Вибір: ";
int elementFind;
cin >> elementFind ;
cout << endl;
newList.findElement(elementFind);
}
if (task == 5) {
newList.saveToFile();
}
if (task == 6) {
exit(1);
}
}
}