Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Кашина_СП_ЛБ10

.docx
Скачиваний:
0
Добавлен:
22.09.2026
Размер:
177 Кб
Скачать

Министерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования

«Владимирский государственный университет

имени Александра Григорьевича и Николая Григорьевича Столетовых» (ВлГУ)

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

КАФЕДРА ФИЗИКИ И ПРИКЛАДНОЙ МАТЕМАТИКИ

Лабораторная работа № 10

по дисциплине «Системное программирование»

на тему: «Динамические структуры данных. Списки.»

Выполнил

студент группы ИПсп-123

Кашина Д. А.

Принял

Красильщикова В. В.

Владимир, 2026

Цель работы: получение практических навыков создания линейных динамических структур данных.

Задание:

Ход работы:

Код программы:

заголовочный файл Person.h

#ifndef PERSON_H

#define PERSON_H

#include <cstring>

struct Person {

char surname[50];

char name[50];

int age;

char gender[10];

// Сравнение для упорядочивания (по фамилии, имени, возрасту)

bool operator<(const Person& other) const {

int cmpSurname = strcmp(surname, other.surname);

if (cmpSurname != 0) return cmpSurname < 0;

int cmpName = strcmp(name, other.name);

if (cmpName != 0) return cmpName < 0;

return age < other.age;

}

bool operator==(const Person& other) const {

return strcmp(surname, other.surname) == 0 &&

strcmp(name, other.name) == 0 &&

age == other.age &&

strcmp(gender, other.gender) == 0;

}

};

#endif

заголовочный файл ordered_list.h

#ifndef ORDERED_LIST_H

#define ORDERED_LIST_H

#include "person.h"

#include <iostream>

class OrderedPersonList {

private:

struct Node {

Person data;

Node* next;

Node(const Person& p) : next(nullptr) {

data = p;

}

};

Node* head;

int size;

public:

OrderedPersonList();

~OrderedPersonList();

void add(const Person& p);

void removeByPosition(int pos);

Person getByPosition(int pos) const;

int* findPositionsBySurnameAndName(const char* surname, const char* name, int& resultCount) const;

Person* findPersonsBySurnameAndName(const char* surname, const char* name, int& resultCount) const;

Person* getByAge(int age, int& resultCount) const;

bool empty() const { return head == nullptr; }

int getSize() const { return size; }

void print() const;

void printTable() const;

void printTableWithPersons(Person* persons, int count) const;

};

#endif

Файл с++ ordered_list.cpp

#include "ordered_list.h"

#include <cstring>

#include <iomanip>

#include <string>

using namespace std;

OrderedPersonList::OrderedPersonList() : head(nullptr), size(0) {}

OrderedPersonList::~OrderedPersonList() {

while (head) {

Node* temp = head;

head = head->next;

delete temp;

}

}

void OrderedPersonList::add(const Person& p) {

Node* curr = head;

while (curr) {

if (curr->data == p) {

throw "Ошибка: Человек с такими данными уже существует в списке!";

}

curr = curr->next;

}

Node* newNode = new Node(p);

if (!head || p < head->data) {

newNode->next = head;

head = newNode;

}

else {

Node* prev = head;

curr = head->next;

while (curr && curr->data < p) {

prev = curr;

curr = curr->next;

}

prev->next = newNode;

newNode->next = curr;

}

++size;

}

void OrderedPersonList::removeByPosition(int pos) {

if (pos < 0 || pos >= size) {

throw "Ошибка: Позиция превышает длину списка!";

}

Node* toDelete = nullptr;

if (pos == 0) {

toDelete = head;

head = head->next;

}

else {

Node* prev = head;

for (int i = 0; i < pos - 1; ++i) {

prev = prev->next;

}

toDelete = prev->next;

prev->next = toDelete->next;

}

delete toDelete;

--size;

}

Person OrderedPersonList::getByPosition(int pos) const {

if (pos < 0 || pos >= size) {

throw "Ошибка: Позиция превышает длину списка!";

}

Node* curr = head;

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

curr = curr->next;

}

return curr->data;

}

int* OrderedPersonList::findPositionsBySurnameAndName(const char* surname,

const char* name,

int& resultCount) const {

int* tempArray = new int[size];

resultCount = 0;

Node* curr = head;

int pos = 0;

while (curr) {

if (strcmp(curr->data.surname, surname) == 0 &&

strcmp(curr->data.name, name) == 0) {

tempArray[resultCount] = pos;

resultCount++;

}

curr = curr->next;

pos++;

}

if (resultCount == 0) {

delete[] tempArray;

resultCount = 1;

int* result = new int[1];

result[0] = -1;

return result;

}

int* result = new int[resultCount];

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

result[i] = tempArray[i];

}

delete[] tempArray;

return result;

}

Person* OrderedPersonList::findPersonsBySurnameAndName(const char* surname,

const char* name,

int& resultCount) const {

Person* tempArray = new Person[size];

resultCount = 0;

Node* curr = head;

while (curr) {

if (strcmp(curr->data.surname, surname) == 0 &&

strcmp(curr->data.name, name) == 0) {

tempArray[resultCount] = curr->data;

resultCount++;

}

curr = curr->next;

}

if (resultCount == 0) {

delete[] tempArray;

return nullptr;

}

Person* result = new Person[resultCount];

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

result[i] = tempArray[i];

}

delete[] tempArray;

return result;

}

Person* OrderedPersonList::getByAge(int age, int& resultCount) const {

Person* tempArray = new Person[size];

resultCount = 0;

Node* curr = head;

while (curr) {

if (curr->data.age == age) {

tempArray[resultCount] = curr->data;

resultCount++;

}

curr = curr->next;

}

if (resultCount == 0) {

delete[] tempArray;

return nullptr;

}

Person* result = new Person[resultCount];

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

result[i] = tempArray[i];

}

delete[] tempArray;

return result;

}

void OrderedPersonList::print() const {

if (!head) {

cout << "Список пуст." << endl;

return;

}

Node* curr = head;

int pos = 0;

while (curr) {

cout << "[" << pos << "] "

<< curr->data.surname << " "

<< curr->data.name << ", "

<< curr->data.age << " лет, "

<< curr->data.gender << endl;

curr = curr->next;

pos++;

}

}

void OrderedPersonList::printTable() const {

if (!head) {

cout << "\nСписок пуст. Нет данных для отображения!" << endl;

return;

}

cout << "\nИнформация о людях (" << size << " чел.):\n" << endl;

cout << left;

cout << "| " << setw(4) << "N"

<< "| " << setw(20) << "Фамилия"

<< "| " << setw(15) << "Имя"

<< "| " << setw(8) << "Возраст"

<< "| " << setw(8) << "Пол" << " |" << endl;

cout << "|" << string(5, '-')

<< "|" << string(21, '-')

<< "|" << string(16, '-')

<< "|" << string(9, '-')

<< "|" << string(10, '-') << "|" << endl;

Node* curr = head;

int pos = 1;

while (curr) {

cout << "| " << setw(4) << pos

<< "| " << setw(20) << curr->data.surname

<< "| " << setw(15) << curr->data.name

<< "| " << setw(8) << curr->data.age

<< "| " << setw(8) << curr->data.gender << " |" << endl;

curr = curr->next;

pos++;

}

cout << endl;

}

void OrderedPersonList::printTableWithPersons(Person* persons, int count) const {

if (count == 0 || persons == nullptr) {

cout << "\nЛюди не найдены!" << endl;

return;

}

cout << "\nНайдено людей (" << count << "):\n" << endl;

cout << left;

cout << "| " << setw(4) << "N"

<< "| " << setw(20) << "Фамилия"

<< "| " << setw(15) << "Имя"

<< "| " << setw(8) << "Возраст"

<< "| " << setw(8) << "Пол" << " |" << endl;

cout << "|" << string(5, '-')

<< "|" << string(21, '-')

<< "|" << string(16, '-')

<< "|" << string(9, '-')

<< "|" << string(10, '-') << "|" << endl;

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

cout << "| " << setw(4) << (i + 1)

<< "| " << setw(20) << persons[i].surname

<< "| " << setw(15) << persons[i].name

<< "| " << setw(8) << persons[i].age

<< "| " << setw(8) << persons[i].gender << " |" << endl;

}

cout << endl;

}

главный код программы laba10.cpp

#include <iostream>

#include <string>

#include <iomanip>

#include <windows.h>

#include "ordered_list.h"

using namespace std;

// ==================== ФУНКЦИИ ВАЛИДАЦИИ ====================

void clearInputBuffer() {

cin.clear();

cin.ignore(10000, '\n');

}

bool isOnlyLetters(const string& str) {

if (str.empty()) return false;

for (char c : str) {

unsigned char uc = static_cast<unsigned char>(c);

bool isRussian = (uc >= 192 && uc <= 255) || uc == 168 || uc == 184;

bool isEnglish = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');

bool isHyphen = (c == '-');

if (!isRussian && !isEnglish && !isHyphen) {

return false;

}

}

if (str[0] == '-' || str[str.length() - 1] == '-') return false;

for (size_t i = 0; i < str.length() - 1; ++i) {

if (str[i] == '-' && str[i + 1] == '-') return false;

}

return true;

}

bool isOnlyDigits(const string& str) {

if (str.empty()) return false;

for (char c : str) {

if (!isdigit(static_cast<unsigned char>(c))) {

return false;

}

}

return true;

}

string inputText(const string& prompt, bool allowEmpty = false) {

string input;

while (true) {

cout << prompt;

getline(cin, input);

if (input.empty() && !allowEmpty) {

cout << "Ошибка: Поле не может быть пустым!" << endl;

continue;

}

return input;

}

}

string inputName(const string& prompt) {

string input;

while (true) {

cout << prompt;

getline(cin, input);

size_t start = input.find_first_not_of(" \t");

if (start == string::npos) {

cout << "Ошибка: Введите данные!" << endl;

continue;

}

size_t end = input.find_last_not_of(" \t");

input = input.substr(start, end - start + 1);

if (input.find(' ') != string::npos) {

cout << "Ошибка: Фамилия не должна содержать пробелов!" << endl;

continue;

}

if (!isOnlyLetters(input)) {

cout << "Ошибка: Используйте только буквы и дефис!" << endl;

continue;

}

return input;

}

}

int inputInt(const string& prompt, int minVal, int maxVal) {

string input;

int value;

while (true) {

cout << prompt;

getline(cin, input);

if (!isOnlyDigits(input)) {

cout << "Ошибка: Введите число!" << endl;

continue;

}

value = stoi(input);

if (value < minVal || value > maxVal) {

cout << "Ошибка: Значение должно быть от " << minVal << " до " << maxVal << "!" << endl;

continue;

}

return value;

}

}

string inputGender() {

string gender;

while (true) {

cout << "Введите пол (М/Ж): ";

getline(cin, gender);

if (gender == "М" || gender == "м" || gender == "M" || gender == "m") {

return "М";

}

else if (gender == "Ж" || gender == "ж" || gender == "F" || gender == "f") {

return "Ж";

}

else {

cout << "Ошибка: Введите 'М' или 'Ж'!" << endl;

}

}

}

// ==================== ОСНОВНЫЕ ФУНКЦИИ ====================

void clearScreen() {

system("cls");

}

void pause() {

cout << "\nДля продолжения нажмите Enter...";

cin.get();

}

void addPerson(OrderedPersonList& list) {

cout << "\n--- Добавление нового человека ---" << endl;

Person newPerson;

string surname = inputName("Введите фамилию: ");

string name = inputName("Введите имя: ");

int age = inputInt("Введите возраст (0-150): ", 0, 150);

string gender = inputGender();

strcpy_s(newPerson.surname, surname.c_str());

strcpy_s(newPerson.name, name.c_str());

newPerson.age = age;

strcpy_s(newPerson.gender, gender.c_str());

try {

list.add(newPerson);

cout << "\nЧеловек успешно добавлен в список!" << endl;

}

catch (const char* msg) {

cout << "\n" << msg << endl;

}

}

void removePerson(OrderedPersonList& list) {

if (list.empty()) {

cout << "\nСписок пуст. Нет данных для удаления!" << endl;

return;

}

cout << "\n--- Удаление человека ---" << endl;

list.printTable();

int pos = inputInt("Введите порядковый номер для удаления (1-" + to_string(list.getSize()) + "): ", 1, list.getSize());

try {

list.removeByPosition(pos - 1);

cout << "\nЧеловек успешно удален!" << endl;

}

catch (const char* msg) {

cout << "\n" << msg << endl;

}

}

void getPersonByPosition(const OrderedPersonList& list) {

if (list.empty()) {

cout << "\nСписок пуст!" << endl;

return;

}

cout << "\n--- Получение человека по номеру позиции ---" << endl;

int pos = inputInt("Введите номер позиции (от 1 до " + to_string(list.getSize()) + "): ", 1, list.getSize());

try {

Person p = list.getByPosition(pos - 1);

cout << "\nЧеловек на позиции " << pos << ":" << endl;

cout << "Фамилия: " << p.surname << endl;

cout << "Имя: " << p.name << endl;

cout << "Возраст: " << p.age << endl;

cout << "Пол: " << p.gender << endl;

}

catch (const char* msg) {

cout << "\n" << msg << endl;

}

}

void searchBySurnameAndName(const OrderedPersonList& list) {

if (list.empty()) {

cout << "\nСписок пуст!" << endl;

return;

}

cout << "\n--- Поиск человека по фамилии и имени ---" << endl;

string surname = inputName("Введите фамилию: ");

string name = inputName("Введите имя: ");

int count;

Person* found = list.findPersonsBySurnameAndName(surname.c_str(), name.c_str(), count);

if (found == nullptr) {

cout << "\nЧеловек с фамилией '" << surname << "' и именем '" << name << "' не найден!" << endl;

}

else {

list.printTableWithPersons(found, count);

delete[] found;

}

}

void searchByAge(const OrderedPersonList& list) {

if (list.empty()) {

cout << "\nСписок пуст!" << endl;

return;

}

cout << "\n--- Поиск людей по возрасту ---" << endl;

int age = inputInt("Введите возраст для поиска: ", 0, 150);

int count;

Person* found = list.getByAge(age, count);

if (found == nullptr) {

cout << "\nЛюди с возрастом " << age << " лет не найдены!" << endl;

}

else {

list.printTableWithPersons(found, count);

delete[] found;

}

}

void initTestData(OrderedPersonList& list) {

Person p1 = { "Сергеев", "Иван", 25, "М" };

Person p2 = { "Иванова", "Анна", 22, "Ж" };

Person p3 = { "Акимов", "Иван", 25, "М" };

Person p4 = { "Хомяков", "Олег", 23, "М" };

Person p5 = { "Трубицина", "Мария", 22, "Ж" };

Person p6 = { "Иванов", "Иван", 25, "М" };

try {

list.add(p1);

list.add(p2);

list.add(p3);

list.add(p4);

list.add(p5);

list.add(p6);

}

catch (const char* msg) {

// Игнорируем дубликаты при инициализации

}

}

// ==================== ГЛАВНАЯ ФУНКЦИЯ ====================

int main() {

SetConsoleCP(1251);

SetConsoleOutputCP(1251);

setlocale(LC_ALL, "Russian");

OrderedPersonList list;

initTestData(list);

int choice;

while (true) {

clearScreen();

cout << "==============================================" << endl;

cout << " УПРАВЛЕНИЕ СПИСКОМ ЛЮДЕЙ (Вариант 4)" << endl;

cout << "==============================================" << endl;

cout << "1 - ДОБАВИТЬ ЧЕЛОВЕКА В СПИСОК" << endl;

cout << "2 - УДАЛИТЬ ЧЕЛОВЕКА ИЗ СПИСКА (по порядковому номеру)" << endl;

cout << "3 - ВЫВОД ИНФОРМАЦИИ ОБО ВСЕХ ЛЮДЯХ" << endl;

cout << "4 - ПОИСК ЧЕЛОВЕКА ПО ФАМИЛИИ И ИМЕНИ" << endl;

cout << "5 - ПОИСК ЛЮДЕЙ ПО ВОЗРАСТУ" << endl;

cout << "6 - ПОЛУЧИТЬ ЧЕЛОВЕКА ПО НОМЕРУ ПОЗИЦИИ" << endl;

cout << "7 - ВЫХОД ИЗ ПРОГРАММЫ" << endl;

cout << "==============================================" << endl;

choice = inputInt("Выбор: ", 1, 7);

switch (choice) {

case 1:

clearScreen();

addPerson(list);

pause();

break;

case 2:

clearScreen();

removePerson(list);

pause();

break;

case 3:

clearScreen();

list.printTable();

pause();

break;

case 4:

clearScreen();

searchBySurnameAndName(list);

pause();

break;

case 5:

clearScreen();

searchByAge(list);

pause();

break;

case 6:

clearScreen();

getPersonByPosition(list);

pause();

break;

case 7:

cout << "\nВыход из программы. До свидания!" << endl;

return 0;

}

}

return 0;

}

Результат работы программы:

Вывод: в ходе лабораторной работы были получены практические навыки создания линейных динамических структур данных.

Соседние файлы в предмете Системное программирование