├── README ├── compile_and_run.sh ├── var.3 ├── Проекты │ ├── main.cpp │ └── func.h ├── Наследование │ ├── class.h │ ├── main.cpp │ └── class.cpp ├── Текстовые файлы.CPP ├── Двоичные файлы.CPP ├── Перегрузка.cpp ├── Классы.cpp ├── Функции.CPP └── Динамич.структ.cpp ├── vs_compatibility_for_linux.h └── var.6 ├── 10_classes ├── list.h ├── main.cpp └── list.cpp ├── 12_overloading ├── list.h ├── main.cpp └── list.cpp ├── 11_inheritance └── main.cpp └── 9_dynamic_lists └── main.cpp /README: -------------------------------------------------------------------------------- 1 | Лабораторные работы по С++, 2 курс МИЭТ 2 | -------------------------------------------------------------------------------- /compile_and_run.sh: -------------------------------------------------------------------------------- 1 | rm prog 2 | clear 3 | g++ $1 -o prog 4 | ./prog 5 | -------------------------------------------------------------------------------- /var.3/Проекты/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "func.h" 5 | const int r1=7; 6 | const int r2=8; 7 | const int r3=6; 8 | void main() 9 | { 10 | int M[r1],L[r2],C[r3]; 11 | randomize(); 12 | clrscr(); 13 | form(M,L,C,r1,r2,r3); 14 | func(M,L,C,r1,r2,r3); 15 | getch(); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /vs_compatibility_for_linux.h: -------------------------------------------------------------------------------- 1 | /* 2 | Данный файл предназначен для упрощения компиляции проектов Visual Studio под gcc 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | void randomize() 9 | { 10 | srand ( time(NULL) ); 11 | } 12 | 13 | int random(int num) 14 | { 15 | return rand() % num; 16 | } 17 | 18 | void clrscr(){ 19 | system("clear"); 20 | } 21 | -------------------------------------------------------------------------------- /var.3/Наследование/class.h: -------------------------------------------------------------------------------- 1 | class massiv 2 | { 3 | public: 4 | int count; 5 | int *num; 6 | massiv(int); 7 | virtual int Count(); 8 | void Print(); 9 | void Add(int, int); 10 | }; 11 | 12 | class stek: public massiv 13 | { 14 | public: 15 | int top; 16 | stek(int); 17 | virtual int Count(); 18 | void pop(int); 19 | }; 20 | 21 | class squeue: public massiv 22 | { 23 | public: 24 | int top; 25 | squeue(int); 26 | virtual int Count(); 27 | void add(int); 28 | }; 29 | -------------------------------------------------------------------------------- /var.3/Текстовые файлы.CPP: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void main() 5 | 6 | { FILE*ft,*zp; 7 | int c='a',d,ch,j; 8 | ft=fopen("inp.txt","w"); 9 | if(!ft) { puts("ne cozdat fail\n"); 10 | exit(1); 11 | } 12 | 13 | fprintf(ft,"fhjhhahfjahwiuoweiitudbcanvczxccdfee"); 14 | fclose(ft); 15 | 16 | zp=fopen("g.txt","w"); 17 | for(j=0;j<5;j++) 18 | { 19 | d=0; 20 | ft=fopen("inp.txt","r"); 21 | while((ch=fgetc(ft))!=EOF) 22 | {if(c==ch) 23 | { d++; 24 | printf("===%c",c); 25 | } 26 | } 27 | fclose(ft); 28 | fprintf(zp,"bykv(%c)-%d\n",c,d); 29 | c++; 30 | } 31 | 32 | fclose(zp); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /var.3/Наследование/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "class.h" 3 | 4 | 5 | void main() 6 | { 7 | massiv m(10); 8 | cout<<"The massiv: \n"; 9 | m.Print(); 10 | cout< 2 | #include 3 | 4 | main() 5 | 6 | { 7 | FILE*f_out=fopen("Int.dat","w+b"); 8 | int i,e=0; 9 | int arr[100],kon[200]; 10 | int number; 11 | randomize(); 12 | 13 | if(! f_out) { puts("ne cozdat fail\n"); 14 | exit(1); 15 | } 16 | for(i=0;i<100;i++) 17 | { number=random(100)-50; 18 | fwrite(&number,sizeof(int),1,f_out); 19 | } 20 | fclose(f_out); 21 | 22 | f_out=fopen("Int.dat","r+b"); 23 | if(!f_out) 24 | { puts("ne proghest\n"); 25 | exit(1); 26 | } 27 | fread(&arr,sizeof(int),100,f_out); 28 | e=0; 29 | for(i=0;i<100;i++) 30 | { if(arr[i]%2!=0) 31 | { kon[e]=arr[i]; 32 | e++; 33 | printf("e`111-%d,uu-%d\n",e,i); 34 | } 35 | //printf("gggggd%d\n",i); 36 | } 37 | for(i=0;i<100;i++) 38 | {kon[e]=arr[i]; 39 | e++; 40 | // printf("eeeeeee%d\n",e); 41 | } 42 | fclose(f_out); 43 | 44 | f_out=fopen("Int.dat","wb"); 45 | fwrite(&kon,sizeof(int),e,f_out); 46 | fclose(f_out); 47 | return 0; 48 | } 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /var.3/Проекты/func.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void form (int MM[],int LL[],int CC[],int r1,int r2, int r3) 6 | { 7 | for (i=0;i 2 | #include 3 | #include 4 | 5 | class scl 6 | { 7 | char str[90]; 8 | 9 | public: 10 | scl(char hello[90]) 11 | {strcpy(str,hello);} 12 | 13 | scl(const scl&scl1); 14 | void printclass() 15 | { 16 | cout<=0;i--) 27 | str[i]=tolower(str[i]); 28 | } 29 | 30 | }; 31 | 32 | 33 | scl::scl(const scl&scl1) 34 | { 35 | strcpy(str,scl1.str); 36 | } 37 | 38 | void main() 39 | 40 | { 41 | scl scl1("INTEL"),scl3("4"),scl4("poopPPPPm"); 42 | scl1.printclass(); 43 | scl4.printclass(); 44 | 45 | //scl scl2(scl1); 46 | //scl1.printclass(); 47 | //scl2.printclass(); 48 | cout<<"__________________________________________\n"; 49 | scl1+scl4+scl3; 50 | scl1++; 51 | scl1.printclass(); 52 | int k; 53 | cin>>k; 54 | } 55 | -------------------------------------------------------------------------------- /var.3/Наследование/class.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "class.h" 5 | int i; 6 | 7 | 8 | massiv::massiv(int n) 9 | { 10 | num=new int[n]; 11 | count=n; 12 | for(i=0; i 2 | #include 3 | #include 4 | 5 | class scl 6 | { 7 | char str[90]; 8 | 9 | public: 10 | scl(char hello[90]) 11 | {strcpy(str,hello);} 12 | 13 | scl(const scl&scl1); 14 | void printclass() 15 | { 16 | cout<=0;i--) 27 | str[i]=tolower(str[i]); 28 | } 29 | 30 | }; 31 | 32 | 33 | scl::scl(const scl&scl1) 34 | { 35 | strcpy(str,scl1.str); 36 | } 37 | 38 | void main() 39 | 40 | { 41 | scl scl1("RRRRRRR"),scl3("!Q!Q!Q"),scl4("SUSCium"); 42 | scl1.printclass(); 43 | scl4.printclass(); 44 | 45 | //scl scl2(scl1); 46 | //scl1.printclass(); 47 | //scl2.printclass(); 48 | cout<<"+++++++++++++++++++++++++++++++++++++++++=\n"; 49 | scl1.slozenie(scl3); 50 | scl1.slozenie(scl4); 51 | scl1.ymeniscenie(); 52 | 53 | scl1.printclass(); 54 | int k; 55 | cin>>k; 56 | } -------------------------------------------------------------------------------- /var.3/Функции.CPP: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | const int r1=7; 7 | const int r2=8; 8 | const int r3=6; 9 | void func (int M[r1],int L[r3],int C[r2]); 10 | 11 | void main() 12 | {randomize(); 13 | int i,j,k; 14 | int MM[r1],LL[r3],CC[r2]; 15 | for (i=0;i321) и поиска подсписка в списке. 9 | */ 10 | 11 | #include 12 | using namespace std; 13 | #include 14 | #include 15 | 16 | #include 17 | #include "list.h" 18 | #include "list.cpp" 19 | 20 | int main (void) 21 | { 22 | // Каждый раз генерировать разные случайные числа 23 | srand ( time(NULL) ); 24 | 25 | // создание списка из 20 элементов 26 | List l1(10); 27 | 28 | // создание списка путем копирования l1 29 | List l2(l1); 30 | 31 | cout << "Список l1" << endl; 32 | l1.print(); 33 | 34 | cout << "Список l2, копия l1" << endl; 35 | l2.print(); 36 | 37 | cout << "Инвертированный список l1" << endl; 38 | l1.invert(); 39 | l1.print(); 40 | 41 | // Список l3 будет использоваться для поиска подсписка 42 | List l3(1); 43 | 44 | // Найти вхождения списка l3 в l1 45 | l1.search(l3); 46 | 47 | return 1; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /var.6/12_overloading/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Лабораторная работа № 12 3 | Программирование с использованием наследования классов. 4 | 5 | Вариант 6 6 | Определить класс список элементов. В определение класса включить два конструктора 7 | для определения списка по его размеру и путем копирования другого списка. 8 | 9 | Определить операции над списком: 10 | & формирование нового списка из двух списков так, 11 | что каждый элемент информационного поля нового списка удовлетворяет условию: с = (а < b ) ? a : b 12 | 13 | Определить функцию-элемент класса для удаления элемента с определенного места списка. 14 | */ 15 | 16 | #include 17 | using namespace std; 18 | #include 19 | #include 20 | 21 | #include "list.h" 22 | #include "list.cpp" 23 | 24 | int main(){ 25 | // Каждый раз генерировать разные случайные числа 26 | srand ( time(NULL) ); 27 | 28 | List l1(10); 29 | List l2(l1); 30 | List l3 (10); 31 | 32 | List l4(10); 33 | 34 | cout << "Список l1: " << endl; 35 | l1.print(); 36 | 37 | cout << "Список l2, копия l1:" << endl; 38 | l2.print(); 39 | 40 | cout << endl << "Список l3: " << endl; 41 | l3.print(); 42 | 43 | l4 = l1 & l3; 44 | cout << endl << "Список l4 = l1 & l3. 'с = (а < b ) ? a : b' : " << endl; 45 | l4.print(); 46 | 47 | l4.exclude(3); 48 | cout << endl << "Список l4 без 3 элемента: " << endl; 49 | l4.print(); 50 | 51 | cout << endl; 52 | 53 | return 1; 54 | } 55 | -------------------------------------------------------------------------------- /var.3/Динамич.структ.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct list 6 | { 7 | int info; 8 | list *next, *prev; 9 | }; 10 | 11 | int NewEl(list* &Head, list* &Tail, int pos) 12 | { 13 | int i; 14 | list *X, *Y; 15 | 16 | if (pos==1) 17 | { 18 | Y=new list; 19 | Y->info=random(10); 20 | Y->prev=NULL; 21 | Y->next=Head; 22 | Head->prev=Y; 23 | Head=Y; 24 | } 25 | else 26 | { 27 | X=new list; 28 | X=Head; 29 | for (i=0;i<=pos-2;i++) 30 | { 31 | if (X!=Tail) 32 | X=X->next; 33 | else 34 | return 1; 35 | } 36 | Y=new list; 37 | Y->info=random(10); 38 | Y->prev=X->prev; 39 | X->prev->next=Y; 40 | Y->next=X; 41 | X->prev=Y; 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | void Replace(list *Head, list *Tail, int El1, int El2) 48 | { 49 | list *X; 50 | X=new list; 51 | X=Head; 52 | 53 | while (X!=Tail) 54 | { 55 | if (X->info==El1) 56 | X->info=El2; 57 | X=X->next; 58 | } 59 | if (X->info==El1) 60 | X->info=El2; 61 | } 62 | 63 | void PrintList(list *Head, list *Tail) 64 | { 65 | list *X; 66 | X=new list; 67 | X=Head; 68 | 69 | while (X!=Tail) 70 | { 71 | printf("%d ",X->info); 72 | X=X->next; 73 | } 74 | printf("%d ",X->info); 75 | } 76 | 77 | void main() 78 | { 79 | clrscr(); 80 | randomize(); 81 | 82 | list *Head, *Tail; 83 | int el1, el2, i, n; 84 | 85 | Head=new list; 86 | Tail=new list; 87 | Head->info=random(10); 88 | Head->prev=NULL; 89 | Head->next=NULL; 90 | Tail=Head; 91 | printf("Enter number of elements: "); 92 | scanf("%d",&n); 93 | for (i=1;i<=n-1;i++) 94 | NewEl(Head,Tail,1); 95 | 96 | printf("Your list: "); 97 | PrintList(Head,Tail); 98 | printf("\nEnter element to replace: "); 99 | scanf("%d",&el1); 100 | printf("Enter element to replace with: "); 101 | scanf("%d",&el2); 102 | Replace(Head,Tail,el1,el2); 103 | printf("New list: "); 104 | PrintList(Head,Tail); 105 | 106 | delete Head; 107 | delete Tail; 108 | 109 | getch(); 110 | } -------------------------------------------------------------------------------- /var.6/11_inheritance/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Лабораторная работа № 11 3 | Программирование с использованием наследования классов. 4 | 5 | Вариант 6 6 | Разработать программу с использованием наследования классов, реализующую классы: 7 | - работник больницы 8 | - медсестра 9 | - хирург 10 | Используя виртуальные функции, не зная с объектом какого класса вы работаете, выведите на экран возраст и название должности. 11 | */ 12 | 13 | #include 14 | using namespace std; 15 | #include 16 | 17 | // Базовй класс работника 18 | // Так как у всех работников есть общие параметры такие как age и job, определяем их в базовом классе 19 | class Employee 20 | { 21 | public: 22 | int age; 23 | const char *job; 24 | 25 | // Конструктор 26 | Employee(int _age){ 27 | age = _age; 28 | } 29 | 30 | // Вывод данных о сотруднике 31 | // Дирректива virtual говорит нам что эта функция может переопределяться в наследуемых классах 32 | // В данной ситуации функция будет вызвана если мы не определим её у наследуемого класса 33 | virtual void printInfo(){ 34 | cout << "Вызвано из базового класса:" << endl; 35 | cout << "Данные о работнике" << endl; 36 | cout << "Возраст: " << age << " лет"<< endl; 37 | cout << "Должность: " << job << endl; 38 | cout << endl; 39 | } 40 | }; 41 | 42 | // Класс работника больницы, наследуем от Employee 43 | class HospitalWorker: Employee 44 | { 45 | public: 46 | // Выполняем конструктор HospitalWorker, и также выполняем конструктор базового класса Employee с параметром age 47 | HospitalWorker(int age):Employee(age){ 48 | // Устанавливаем тип работы 49 | job = "работник больницы"; 50 | } 51 | 52 | // Переопределяем информацию о работнике 53 | void virtual printInfo(){ 54 | cout << "Я "<< job << " и мою полы" << endl; 55 | cout << "Мне " << age << endl; 56 | cout << endl; 57 | } 58 | }; 59 | 60 | // Класс Медсестра, наследуем от Employee 61 | // Не перегружаем у него фунцию printInfo, будет использоваться функция описанная в Employee 62 | class Nurse: Employee 63 | { 64 | public: 65 | Nurse(int age):Employee(age){ 66 | job = "медсестра"; 67 | } 68 | }; 69 | 70 | // Класс Хирург, наследуем от Employee 71 | class Surgeon: Employee 72 | { 73 | public: 74 | Surgeon(int age):Employee(age){ 75 | job = "хирург"; 76 | } 77 | 78 | // Перегружаем функцию printInfo от Employee 79 | void virtual printInfo(){ 80 | cout << "Я "<< job << " и люблю резать людей" << endl; 81 | cout << "Мне " << age << endl; 82 | cout << endl; 83 | } 84 | }; 85 | 86 | 87 | int main(){ 88 | // Ссылка на объект базового типа 89 | Employee *employee; 90 | 91 | // Создаем 3-х работников согласно заданию 92 | HospitalWorker* worker = new HospitalWorker(63); 93 | Nurse* nurse = new Nurse(35); 94 | Surgeon* surgeon = new Surgeon(40); 95 | 96 | // Приводим объект к типу Employee 97 | employee = (Employee *)worker; 98 | // Будет вызвана функия printInfo класса HospitalWorker 99 | // Если бы мы не определили функцию как virtual, тогда бы вызвался метод базового класса Employee 100 | employee->printInfo(); 101 | 102 | // Приводим объект к типу Employee 103 | employee = (Employee *)nurse; 104 | employee->printInfo(); 105 | // Будет вызвана функция printInfo класса Employee, так как мы не перегрузили её 106 | 107 | // Приводим объект к типу Employee 108 | employee = (Employee *)surgeon; 109 | // Будет вызвана функция printInfo класса Surgeon 110 | employee->printInfo(); 111 | 112 | return 1; 113 | } 114 | -------------------------------------------------------------------------------- /var.6/9_dynamic_lists/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Лабораторная работа № 9 3 | Программирование задач с использованием динамических структур данных на языке С++ 4 | 5 | Вариант 6 6 | Описать функцию, которая вставляет в стэк К новый элемент L1 за каждым вхождением элемента L. 7 | Значения элементов L и L1 ввести с клавиатуры. 8 | */ 9 | 10 | 11 | #include 12 | using namespace std; 13 | #include 14 | #include 15 | 16 | //Структура элемента стэка 17 | struct Node 18 | { 19 | //В data будут хранится данные 20 | int data; 21 | 22 | // link ссылка на следующий элемент 23 | Node *next; 24 | }; 25 | 26 | // Создание синонима NodePtr для указателя на нашу структуру Node 27 | typedef Node* NodePtr; 28 | 29 | 30 | /* 31 | Вывод стэка на экран 32 | head - головной элемент стэка 33 | */ 34 | void PrintList(NodePtr head){ 35 | NodePtr current; // Указатель на текущий элемент 36 | 37 | // Установим в начало 38 | current = head; 39 | 40 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 41 | while(current != NULL) 42 | { 43 | // Вывод значения текущего элемента 44 | cout << current->data << ' '; 45 | 46 | // Переходим к следующему элементу 47 | current = current->next; 48 | } 49 | 50 | // перейдем на следующую строку 51 | cout <> N; // Ожидаем ввода пользователя 72 | 73 | // Формируем стек из N элементов 74 | for (int i = 0; idata = rand()%10 - 5; 84 | 85 | // Устанавливаем значение link в NULL, так как это первый элемент нашего стэка 86 | head->next = NULL; 87 | } 88 | else 89 | { 90 | // Создаем новый элемент типа Node 91 | current = new Node; 92 | 93 | current->data = rand()%10 - 5; 94 | 95 | // Для нового элемента, следующим будет последний созданный, который постоянно находится в head 96 | current->next = head; 97 | 98 | // Теперь первым элементом в стэке должен стать current 99 | head = current; 100 | } 101 | } 102 | 103 | // Выведем только что сгенерированный список 104 | cout << "Список: "; 105 | PrintList(head); 106 | 107 | cout << "Введите элемент L для поиска: "; 108 | cin >> L; 109 | cout << endl; 110 | 111 | cout << "Введите элемент L1 для вставки: "; 112 | cin >> L1; 113 | cout << endl; 114 | 115 | 116 | // Для выполнения задачи, нам необходимо сделать цикл по всем элементам списка 117 | // Установим на начало стэка 118 | current = head; 119 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 120 | while(current != NULL) 121 | { 122 | if(current->data == L){ 123 | // Если нашли элемент с значением L, то создаем новый элемент, 124 | // для вставки в цикл, и задаем ему значение L1 125 | new_element = new Node; 126 | new_element->data = L1; 127 | 128 | //Мы должны вставить новый элемент в стэк 129 | // Схема вставки: 130 | // Было: current --> next 131 | // Надо: current --> new --> next 132 | new_element->next = current->next; 133 | current->next = new_element; 134 | 135 | // Уставнавливаем текущим элементом наш новосозданный new_element 136 | current = new_element; 137 | } 138 | 139 | // Переходим к следующему элементу 140 | current = current->next; 141 | } 142 | 143 | cout << "Измененный список: "; 144 | // Выведем измененный список 145 | PrintList(head); 146 | 147 | return 1; 148 | } 149 | 150 | 151 | -------------------------------------------------------------------------------- /var.6/12_overloading/list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "list.h" 5 | 6 | List::List(int n) //конструктор инициализирует список из n элементов по принципу "очередь" 7 | { 8 | NodePtr current; // указатель на текущий элемент 9 | 10 | // Обнуляем начальный элемент 11 | head = NULL; 12 | 13 | // Формируем стек из n элементов 14 | for (int i = 0; idata = rand()%10 - 5; 23 | 24 | // Устанавливаем значение link в NULL, так как это первый элемент нашего стэка 25 | head->next = NULL; 26 | } 27 | else 28 | { 29 | // Создаем новый элемент типа Node 30 | current = new Node; 31 | current->data = rand()%10 - 5; 32 | 33 | // Для нового элемента, следующим будет последний созданный, который постоянно находится в head 34 | current->next = head; 35 | // Теперь первым элементом в стэке должен стать current 36 | head = current; 37 | } 38 | } 39 | } 40 | 41 | List::List(List& list_for_copy) 42 | { 43 | // используется для перемещения по списку 44 | // будет являться ссылкой на текущий элемент копируемого списка 45 | NodePtr iterator; 46 | 47 | NodePtr current; // указатель на текущий элемент 48 | NodePtr new_element; // указатель на текущий элемент 49 | 50 | NodePtr tail; // указатель на конец очереди 51 | 52 | 53 | // Обнуляем начальный элемент 54 | head = NULL; 55 | 56 | // Для того что бы скопировать список, мы должны пройтись циклом по всем его элементам 57 | 58 | // Устанавливаем в начало копируемого списка 59 | iterator = list_for_copy.head; 60 | 61 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 62 | while(iterator != NULL) 63 | { 64 | // Если head равно NULL, значит наш стэк еще пуст, и нам надо созать первый элемент 65 | if (head == NULL) 66 | { 67 | // Создаем новый элемент типа Node, который будет первым в стэке 68 | head = new Node; 69 | // Устанавливаем значение копируемого элемента 70 | head->data = iterator->data; 71 | 72 | // Устанавливаем значение link в NULL, так как это первый элемент нашего стэка 73 | head->next = NULL; 74 | 75 | // Так как это первый элемент, то он является и концом 76 | tail = head; 77 | } 78 | else 79 | { 80 | // Создаем новый элемент типа Node 81 | current = new Node; 82 | // Устанавливаем значение копируемого элемента 83 | current->data = iterator->data; 84 | 85 | /* 86 | Если мы будем копировать как стэк, то получим инвертированный список: 87 | дан список который хотим скопировать: 1 -> 2 -> 3 -> 4 88 | 89 | Так как принципом стэка являетсяЖ первый вошел, первый вышел, 90 | то при последовательном копировании списка мы получим: 91 | 92 | 4 -> 3 -> 2 -> 1, ведь головой у копируемого списка была 1 93 | Пример: 94 | 1 итерация: 95 | 96 | 1 97 | ^ 98 | head 99 | 100 | 2 итерация: 101 | 2 -> 1 102 | ^ 103 | head 104 | 105 | Для того что бы это не случилось нужно копироват его как очередь: Первым вошел, первым вышел 106 | Для этого мы всегда храним наш головной элемент в head 107 | и вводим понятие конца очереди tail, который всегда будет указывать на конец очереди: 108 | 1 итерация: 109 | 110 | 1 -> 2 111 | ^ ^ 112 | head tail 113 | 114 | 2 итерация: 115 | 116 | 1 -> 2 -> 3 117 | ^ ^ 118 | head tail 119 | */ 120 | 121 | tail->next = current; 122 | // Теперь последним элементом в стэке должен стать current 123 | tail = current; 124 | } 125 | 126 | // Переходим к следующему элементу копируемого списка 127 | iterator = iterator->next; 128 | } 129 | } 130 | 131 | // Вывод списка 132 | void List::print() 133 | { 134 | NodePtr current; // Указатель на текущий элемент 135 | 136 | // Установим в начало 137 | current = head; 138 | 139 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 140 | while(current != NULL) 141 | { 142 | // Вывод значения текущего элемента 143 | // setw делается для красивого вывода 144 | cout << setw(5) << current->data; 145 | 146 | // Переходим к следующему элементу 147 | current = current->next; 148 | } 149 | 150 | cout << endl; 151 | } 152 | 153 | 154 | /* 155 | & формирование нового списка из двух списков так, 156 | что каждый элемент информационного поля нового списка удовлетворяет условию: с = (а < b ) ? a : b 157 | 158 | Операция очень похоже на конструктор с копированием другого списка 159 | */ 160 | 161 | List& List::operator & (List& list) 162 | { 163 | int calculated_data; // Используется для вычисления заданного условия 164 | 165 | // используется для перемещения по списку 166 | // 2 так как нам нужно проходится по двум спискам 167 | NodePtr iterator, iterator_ext; 168 | 169 | NodePtr new_list_head; // указатель на текущий элемент 170 | 171 | NodePtr current; // указатель на текущий элемент 172 | NodePtr new_element; // указатель на текущий элемент 173 | 174 | NodePtr tail; // указатель на конец очереди 175 | 176 | // Обнуляем начальный элемент 177 | new_list_head = NULL; 178 | 179 | // Устанавливаем в начало списка 180 | iterator = head; 181 | iterator_ext = list.head; 182 | 183 | // Делаем цикл, пока не дойдем до последнего элемента любого из двух списков, у которого next NULL 184 | while(iterator != NULL && iterator_ext != NULL) 185 | { 186 | // Если выполняется условые в скобках, выбираем первое значение, иначе второе 187 | // с = (а < b ) ? a : b 188 | calculated_data = (iterator->data < iterator_ext->data) ? iterator->data : iterator_ext-> data; 189 | 190 | // Если head равно NULL, значит наш стэк еще пуст, и нам надо созать первый элемент 191 | if (new_list_head == NULL) 192 | { 193 | // Создаем новый элемент типа Node, который будет первым в стэке 194 | new_list_head = new Node; 195 | // Устанавливаем значение копируемого элемента 196 | new_list_head->data = calculated_data; 197 | 198 | // Устанавливаем значение link в NULL, так как это первый элемент нашего стэка 199 | new_list_head->next = NULL; 200 | 201 | // Так как это первый элемент, то он является и концом 202 | tail = new_list_head; 203 | } 204 | else 205 | { 206 | // Создаем новый элемент типа Node 207 | current = new Node; 208 | // Устанавливаем значение копируемого элемента 209 | current->data = calculated_data; 210 | 211 | tail->next = current; 212 | // Теперь последним элементом в стэке должен стать current 213 | tail = current; 214 | } 215 | 216 | // Переходим к следующему элементу копируемого списка 217 | iterator = iterator->next; 218 | iterator_ext = iterator_ext->next; 219 | } 220 | 221 | List* new_list = new List(0); 222 | new_list->head = new_list_head; 223 | 224 | return *new_list; 225 | } 226 | 227 | // Удаление элемента из списка, по индексу 228 | void List::exclude(int index){ 229 | //Счетчик элементов 230 | int counter = 0; 231 | 232 | NodePtr iterator; // Используется для хождению по списку 233 | NodePtr previous; // Хранит в себе предыдущий элемент 234 | 235 | // Устанавливаем начальные значения 236 | iterator = head; 237 | previous = NULL; 238 | 239 | while(iterator != NULL) 240 | { 241 | if(counter == index){ 242 | // Если дошли до нужного элемента, то вырежем его из списка 243 | // 1 -> 2 -> 3 244 | // ^ ^ ^ 245 | // previous iterator next 246 | // Хотим вырезать iterator 247 | // 1 -> 3 248 | // ^ ^ 249 | // previous next 250 | 251 | previous->next = iterator->next; 252 | 253 | // Освобождаем память 254 | delete iterator; 255 | 256 | // Выходим из функции 257 | return; 258 | } 259 | 260 | counter++; 261 | 262 | // Текущий элемент становится предыдущим 263 | previous = iterator; 264 | // Переходим к следующему элементу 265 | iterator = iterator->next; 266 | } 267 | } 268 | 269 | // Деструктор - выполняется перед удалением объекта 270 | // Перед удалением, необходимо отчистить память которую мы заняли 271 | List::~ List() 272 | { 273 | NodePtr current;// Ссылка на текущий элемент 274 | 275 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 276 | while(head != NULL) 277 | { 278 | current = head; 279 | 280 | // Переходим к следующему элементу 281 | head = head->next; 282 | 283 | // Очищаем память, занимаемую current 284 | delete current; 285 | } 286 | } 287 | 288 | -------------------------------------------------------------------------------- /var.6/10_classes/list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "list.h" 5 | 6 | List::List(int n) //конструктор инициализирует список из n элементов по принципу "очередь" 7 | { 8 | NodePtr current; // указатель на текущий элемент 9 | 10 | // Обнуляем начальный элемент 11 | head = NULL; 12 | 13 | // Формируем стек из n элементов 14 | for (int i = 0; idata = rand()%10 - 5; 23 | 24 | // Устанавливаем значение link в NULL, так как это первый элемент нашего стэка 25 | head->next = NULL; 26 | } 27 | else 28 | { 29 | // Создаем новый элемент типа Node 30 | current = new Node; 31 | current->data = rand()%10 - 5; 32 | 33 | // Для нового элемента, следующим будет последний созданный, который постоянно находится в head 34 | current->next = head; 35 | // Теперь первым элементом в стэке должен стать current 36 | head = current; 37 | } 38 | } 39 | } 40 | 41 | List::List(List& list_for_copy) 42 | { 43 | // используется для перемещения по списку 44 | // будет являться ссылкой на текущий элемент копируемого списка 45 | NodePtr iterator; 46 | 47 | NodePtr current; // указатель на текущий элемент 48 | NodePtr new_element; // указатель на текущий элемент 49 | 50 | NodePtr tail; // указатель на конец очереди 51 | 52 | 53 | // Обнуляем начальный элемент 54 | head = NULL; 55 | 56 | // Для того что бы скопировать список, мы должны пройтись циклом по всем его элементам 57 | 58 | // Устанавливаем в начало копируемого списка 59 | iterator = list_for_copy.head; 60 | 61 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 62 | while(iterator != NULL) 63 | { 64 | // Если head равно NULL, значит наш стэк еще пуст, и нам надо созать первый элемент 65 | if (head == NULL) 66 | { 67 | // Создаем новый элемент типа Node, который будет первым в стэке 68 | head = new Node; 69 | // Устанавливаем значение копируемого элемента 70 | head->data = iterator->data; 71 | 72 | // Устанавливаем значение link в NULL, так как это первый элемент нашего стэка 73 | head->next = NULL; 74 | 75 | // Так как это первый элемент, то он является и концом 76 | tail = head; 77 | } 78 | else 79 | { 80 | // Создаем новый элемент типа Node 81 | current = new Node; 82 | // Устанавливаем значение копируемого элемента 83 | current->data = iterator->data; 84 | 85 | /* 86 | Если мы будем копировать как стэк, то получим инвертированный список: 87 | дан список который хотим скопировать: 1 -> 2 -> 3 -> 4 88 | 89 | Так как принципом стэка являетсяЖ первый вошел, первый вышел, 90 | то при последовательном копировании списка мы получим: 91 | 92 | 4 -> 3 -> 2 -> 1, ведь головой у копируемого списка была 1 93 | Пример: 94 | 1 итерация: 95 | 96 | 1 97 | ^ 98 | head 99 | 100 | 2 итерация: 101 | 2 -> 1 102 | ^ 103 | head 104 | 105 | Для того что бы это не случилось нужно копироват его как очередь: Первым вошел, первым вышел 106 | Для этого мы всегда храним наш головной элемент в head 107 | и вводим понятие конца очереди tail, который всегда будет указывать на конец очереди: 108 | 1 итерация: 109 | 110 | 1 -> 2 111 | ^ ^ 112 | head tail 113 | 114 | 2 итерация: 115 | 116 | 1 -> 2 -> 3 117 | ^ ^ 118 | head tail 119 | */ 120 | 121 | tail->next = current; 122 | // Теперь последним элементом в стэке должен стать current 123 | tail = current; 124 | } 125 | 126 | // Переходим к следующему элементу копируемого списка 127 | iterator = iterator->next; 128 | } 129 | } 130 | 131 | 132 | void List::invert() 133 | { 134 | // используется для перемещения по списку 135 | // будет являться ссылкой на текущий элемент копируемого списка 136 | NodePtr iterator; 137 | 138 | NodePtr current; // указатель на текущий элемент 139 | NodePtr new_element; // указатель на текущий элемент 140 | NodePtr new_list_head; 141 | 142 | 143 | // Обнуляем начальный элемент 144 | new_list_head = NULL; 145 | 146 | // Для того что бы скопировать список, мы должны пройтись циклом по всем его элементам 147 | 148 | // Устанавливаем в начало списка 149 | iterator = head; 150 | 151 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 152 | while(iterator != NULL) 153 | { 154 | // Если head равно NULL, значит наш стэк еще пуст, и нам надо созать первый элемент 155 | if (new_list_head == NULL) 156 | { 157 | // Создаем новый элемент типа Node, который будет первым в стэке 158 | new_list_head = new Node; 159 | // Устанавливаем значение копируемого элемента 160 | new_list_head->data = iterator->data; 161 | 162 | // Устанавливаем значение link в NULL, так как это первый элемент нашего стэка 163 | new_list_head->next = NULL; 164 | } 165 | else 166 | { 167 | // Создаем новый элемент типа Node 168 | current = new Node; 169 | // Устанавливаем значение копируемого элемента 170 | current->data = iterator->data; 171 | 172 | // Для нового элемента, следующим будет последний созданный, который постоянно находится в head 173 | current->next = new_list_head; 174 | // Теперь первым элементом в стэке должен стать current 175 | new_list_head = current; 176 | } 177 | 178 | // Переходим к следующему элементу копируемого списка 179 | iterator = iterator->next; 180 | } 181 | 182 | head = new_list_head; 183 | } 184 | 185 | // Поиск подсписка search_list 186 | void List::search(List& search_list) 187 | { 188 | cout << endl; 189 | cout << "Поиск списка: " << endl; 190 | search_list.print(); 191 | cout << "В списке: " << endl; 192 | print(); 193 | cout << endl; 194 | 195 | // Счетчик и метка найденного места, для того что бы вывести где найдено 196 | int counter = 0, current = 0; 197 | 198 | // Количество вхождений искомого списка 199 | int founded = 0; 200 | 201 | // используется для перемещения по нашему списку 202 | NodePtr iterator; 203 | 204 | NodePtr current_search; // указатель на текущий элемент, который ищется 205 | 206 | //Начинаем искать с первого элемента списка 207 | current_search = search_list.head; 208 | 209 | iterator = head; 210 | 211 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 212 | while(iterator != NULL){ 213 | // Если мы нашли первый элемент искомого списка, то перейдем к поиску следующего элемента 214 | if(iterator->data == current_search->data) 215 | { 216 | //Ичем следующий элемент 217 | current_search = current_search->next; 218 | 219 | // Если NULL значит мы дошли до конца списка, и он найден 220 | if(current_search == NULL){ 221 | // +2 потому что, +1 берется так как мы считаем от 0, и еще +1 берется от того что current находится на предыдущем элементе 222 | cout << "Найдено соответствие начиная с " << current+2 << " элемента" << endl; 223 | 224 | founded++; 225 | 226 | // Ищем еще вхождения, если их несколько 227 | current = counter; 228 | current_search = search_list.head; 229 | } 230 | } 231 | else 232 | { 233 | // Так как ничего не найдено, то отправной точкой назначем текущий момент 234 | current = counter; 235 | 236 | //Если поиск какого либо элемента завершился неудачей, снова начинаем искать начиная с головного 237 | current_search = search_list.head; 238 | } 239 | 240 | iterator = iterator->next; 241 | 242 | counter++; 243 | } 244 | 245 | cout << "Найдено совпадений: " << founded << endl; 246 | } 247 | 248 | // Вывод списка 249 | void List::print() 250 | { 251 | NodePtr current; // Указатель на текущий элемент 252 | 253 | // Установим в начало 254 | current = head; 255 | 256 | // Делаем цикл, пока не дойдем до последнего элемента, у которого next NULL 257 | while(current != NULL) 258 | { 259 | // Вывод значения текущего элемента 260 | // setw делается для красивого вывода 261 | cout << setw(5) << current->data; 262 | 263 | // Переходим к следующему элементу 264 | current = current->next; 265 | } 266 | 267 | // перейдем на следующую строку 268 | cout <next; 284 | 285 | // Очищаем память, занимаемую current 286 | delete current; 287 | } 288 | } 289 | 290 | --------------------------------------------------------------------------------