Кашина_СП_ЛБ10
.docxМинистерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования
«Владимирский государственный университет
имени Александра Григорьевича и Николая Григорьевича Столетовых» (ВлГУ)
Колледж инновационных технологий и предпринимательства
КАФЕДРА ФИЗИКИ И ПРИКЛАДНОЙ МАТЕМАТИКИ
Лабораторная работа № 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;
}
Результат работы программы:
Вывод: в ходе лабораторной работы были получены практические навыки создания линейных динамических структур данных.
