Программирование на C / C++ / Лабораторная работа №6 / laba11
.docЗадание: Строка таблицы данных содержит следующую информацию о первокурсниках: фамилия, имя, отечество, группа, количество баллов, набранных на вступительных экзаменах.
Требуется найти: перечень групп, в которых максимальное количество студентов, набравших максимальное количество баллов.
Считывание исходного файла с клавиатуры, вывод на экран.
Сортировка:
1)Сортировка групп, в которых максимальное количество студентов, набравших максимальное количество баллов, в алфавитном порядке.
Вывод на экран и в файл.
2)Сортировка фамилий, имен, отчеств в алфавитном порядке.
Вывод на экран и в файл.
3)Сортировка всех групп в алфавитном порядке.
Вывод на экран и в файл.
4)Сортировка по количеству баллов в порядке убывания.
Вывод на экран и в файл.
Цель работы: классы списков.
Блок-схема главной программы:
Программа:
#include<iostream.h> //библиотека функций ввода, вывода
#include<fstream.h> //библиотека файловых функций
#include<string.h> //библиотека строковых функций
#include<conio.h> //библиотека консольных функций
#include<iomanip.h> //библиотека манипулятор
#include<stdlib.h>
const int l=31; //наибольшее возможное количество символов в строке
struct fio
{ //структура fio включает данные студентов:
char fam[l]; //фамилии
char im[l]; //имена
char ot[l]; //отчества
};
struct student
{ //список student включает данные студентов:
fio f; //ФИО
char gr[l]; //группу
int col; //количество баллов
student *next; //указатель на следующий элемент
};
struct gruppa
{ //список gruppa включает данные групп:
char gr[l]; //название группы
int ng; //количество студентов
gruppa *next; //указатель на следующий элемент
};
class dinam //класс dinam
{private:
student *beg1; //указатель на начало списка student
student *end1; // указатель на конец списка student
student *find (fio name); //вспомогательная функция нахождения студентов по ФИО
int m; //количество студентов
gruppa *beg2; // указатель на начало списка gruppa
gruppa *end2; // указатель на конец списка gruppa
int k; //количество групп
public:
dinam() { //конструктор
m=0; k=0;
beg1=NULL; end1=NULL;
beg2=NULL; end2=NULL;
}
~dinam(); //деструктор
void inputstfile();
void outputst();
void perech();
void sortgr();
void outputgrmax();
void outputgrfile();
void alfsortfio();
void outputstfile();
void alfsortgr();
void sortcol();
void add();
void deletefio();
};
void dinam::inputstfile() //ввод из файла
{student*p; //указатель на список student
ifstream fin; //входной поток
char file[l];
cout<<"imya faila:";
cin>>file; //ввод файла
fin.open(file); //открытие файла
if(fin==NULL) //если файл не обнаружен,
{
cout<<"fail ne naiden "; //вывод сообщения об ошибке на экран
getch(); //задержка на экране,
return; //возврат
}
p=new student; //динамическое выделение памяти для списка student
if(p==NULL) //если нет памяти,
{
cout<<"net pamyati "; //вывод сообщения об ошибке на экран,
getch(); //задержка на экране,
exit(1); //выход из программы
}
fin>>p->f.fam>>p->f.im>>p->f.ot>>p->gr>>p->col;
p->next=NULL; //опустошить следующий элемент списка
while (fin.good()) //пока не прекратятся записи в файле
{if (beg1==NULL) //если нет данных в начале списка
beg1=p; //присвоение ему значения элемента списка
else //иначе присвоение следующему
end1->next=p; //после конца списка значения элемента списка
end1=p; //присвоение концу списка значения элемента списка
m++; //увеличение счетчика количества студентов
p=new student;
if(p==NULL)
{
cout<<"net pamyati ";
getch();
exit(1);
}
fin>>p->f.fam>>p->f.im>>p->f.ot>>p->gr>>p->col;
p->next=NULL;
}
delete p; //удаление указателя на список student
}
void dinam:: outputst() //вывод на экран списка student
{student *p; //указатель на список student
int i;
p=beg1; //присвоение элементу значения начала списка
i=0;
while (p!=NULL) //пока не завершится список student
{
cout<<setw(14)<<setiosflags(ios::left)<<p->f.fam
<<setw(11)<<setiosflags(ios::left)<<p->f.im
<<setw(15)<<setiosflags(ios::left)<<p->f.ot
<<setw(6)<<setiosflags(ios::left)<<p->gr
<<setw(10)<<setiosflags(ios::left)<<p->col<<endl;
p=p->next; //переход к следующему элементу
if((i+1)%10==0) getch(); //задержка на экране
i++;
}
getch();
}
void dinam:: perech() //формирование перечня групп, с указанием количества студентов,
{ // набравших максимальное количество баллов (МАХ)
int fl,max;
student *p1; //указатель на список student
gruppa *p2; //указатель на список gruppa
beg2=NULL; end2=NULL; //опустошение начала и конца списка gruppa
p1=beg1; //присвоение элементу списка student значения начала списка
max=p1->col;
while(p1!=NULL) //вычисление максимального количества баллов
{
if (p1->col>=max)
max=p1->col;
p1=p1->next;
}
k=0;
p1=beg1;
while (p1!=NULL) //пока не завершится список student
{
if (p1->col==max) //если количество баллов, набранных студентом, равно МАХ
{
fl=1;
p2=beg2; //присвоение элементу списка gruppa значения начала списка
while (p2!=NULL) //пока не завершится список gruppa
{
if(strcmp(p1->gr,p2->gr)==0) //если этот студент не первый в своей группе, набравший МАХ
{
fl=0;
p2->ng++; //счетчик студентов в группе, набравших МАХ
}
p2=p2->next; //переход к следующему элементу списка gruppa
}
if (fl==1) //если этот студент первый в своей группе, набравший МАХ
{
p2=new gruppa; //динамическое выделение памяти для списка gruppa
if (p2==NULL) //если нет памяти,
{
cout<<"net pamyati"; //вывод сообщения об ошибке на экран,
getch(); //задержка на экране,
exit(1); //выход из программы
}
strcpy(p2->gr,p1->gr); //копирование названия группы в данный перечень групп
p2->ng=1;
p2->next=NULL; //опустошение следующего элемента списка gruppa
if (beg2==NULL) //если нет данных в начале списка gruppa
beg2=p2; //присвоение ему значения элемента списка gruppa
else //иначе присвоение следующему после конца списка значения
end2->next=p2; // элемента списка gruppa
end2=p2; //присвоение концу списка значения элемента списка gruppa
k++; //счетчик групп
}
}
p1=p1->next; //переход к следующему элементу списка student
}
delete p1,p2; //удаление указателей на списки gruppa, student
}
dinam::~dinam() //деструктор
{
student*p1; //указатель на список student
if(beg1!=NULL) //если есть данные в начале списка
{while(beg1!=NULL) //пока есть данные в начале списка
{p1=beg1; //присвоение элементу списка student значения начала списка
beg1=beg1->next; //переход к следующему значению начала списка
delete p1; //удаление указателя на список student
}
end1=NULL; //опустошение конца списка student
m=0;
}
gruppa*p2; //указатель на список gruppa
if(beg2!=NULL) //если есть данные в начале списка
{while(beg2!=NULL) //пока есть данные в начале списка
{p2=beg2; //присвоение элементу списка gruppa значения начала списка
beg2=beg2->next; //переход к следующему значению начала списка
delete p2; //удаление указателя на список gruppa
}
end2=NULL; //опустошение конца списка gruppa
k=0;
}
}
void dinam::sortgr() //сортировка перечня групп (МАХ) в алфавитном порядке
{int fl;
gruppa *p1,*p2,*p3; //указатели на список gruppa
if(beg2==NULL||beg2->next==NULL) //если нет данных в начале списка gruppa или в следующем
//элементе списка gruppa
return; //возврат
do //выполнение действий:
{
fl=0;
p2=beg2; //присвоение элементу (2) списка gruppa значения начала списка
p3=p2->next; // переход элемента (3) к следующему элементу (2)
if(strcmp(p2->gr,p3->gr)>0) //если алфавитный порядок названий групп нарушен
{
p2->next=p3->next; //перестановка данных списка gruppa
p3->next=p2;
beg2=p3;
fl=1;
}
p1=beg2; //присвоение элементу (1) списка gruppa значения начала списка
while(p1->next->next!=NULL) //пока у третьего после элемента (1) есть данные
{p2=p1->next; //переход элемента (2) к следующему элементу (1)
p3=p2->next; //переход элемента (3) к следующему элементу (2)
if(strcmp(p2->gr,p3->gr)>0)
{p2->next=p3->next; // переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; // переход следующего элемента (3) к элементу (2)
p1->next=p3; // переход следующего элемента (1) к элементу (3)
fl=1;
}
p1=p1->next; //переход к следующему элементу (1)
}
} while(fl==1); //пока есть нарушения в алфавитном порядке
end2=p1->next; //присвоение концу списка gruppa
//значения следующего элемента (1)
}
void dinam:: outputgrmax() //вывод на экран перечня групп, в которых
{ //максимальное количество студентов,
int max1; //набравших максимально количество баллов
gruppa *p; //указатель на список gruppa
cout<<"Tablitsa grupp."<<endl;
p=beg2; //присвоение элементу списка gruppa значения начала списка
max1=p->ng;
while(p!=NULL) //вычисление максимального количества студентов,
{if (p->ng>=max1) //набравших МАХ среди всех групп
max1=p->ng;
p=p->next;
}
p=beg2;
while(p!=NULL)
{if (p->ng==max1) //если количество студентов, набравших МАХ,
cout<<setw(6)<<setiosflags(ios::left) //в этой группе равно максимальному
<<p->gr //вывод группы,
<<setw(10)<<setiosflags(ios::left) //количества студентов группы,
<<p->ng<<endl; //набравших МАХ на экран
p=p->next; //переход к следующему элементу
}
getch(); //задержка на экране
}
void dinam:: outputgrfile() //сохранение в файле перечня групп (МАХ)
{gruppa *p; //указатель на список gruppa
ofstream out; //выходной поток
char file[l];
int max1;
cout<<"imya faila:";
cin>>file; //ввод файла
out.open(file); //открытие файла
if (out==NULL) //если файл не найден,
{
cout<<"Fail ne naiden"; //вывод сообщения об ошибке,
getch(); //задержка на экране
return; //возврат
}
p=beg2;
max1=p->ng;
while(p!=NULL)
{if (p->ng>=max1)
max1=p->ng;
p=p->next;
}
out<<"gruppa "<<"kolichestvo studentov MAX "<<endl;
p=beg2;
while(p!=NULL) //пока не завершится список gruppa
{if (p->ng==max1)
out<<setw(6)<<setiosflags(ios::left) //запись в файл группы,
<<p->gr
<<setw(10)<<setiosflags(ios::left) //количества студентов группы,
<<p->ng<<endl; //набравших МАХ
p=p->next; //переход к следующему элементу
}
out.close(); //закрытие файла
}
void dinam:: alfsortfio() //сортировка списка student по ФИО
{int fl; //в алфавитном порядке
student *p1,*p2,*p3; //указатели на список student
if(beg1==NULL||beg1->next==NULL) //если нет данных в начале списка student или в
//следующем элементе списка student
return; // возврат
do //выполнение действий:
{
fl=0;
p2=beg1; //присвоение элементу (2) начального значения
p3=p2->next; //переход элемента (3) к следующему элементу (2)
if(strcmp(p2->f.fam,p3->f.fam)>0) //если алфавитный порядок фамилий нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
else if(strcmp(p2->f.fam,p3->f.fam)==0) //в случае совпадения фамилий сортировка по имени
if(strcmp(p2->f.im,p3->f.im)>0) //если алфавитный порядок имен нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
else if(strcmp(p2->f.im,p3->f.im)==0) //в случае совпадения имен сортировка по отчеству
if(strcmp(p2->f.ot,p3->f.ot)>0) //если алфавитный порядок отчеств нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
p1=beg1; //присвоение элементу начального значения
while(p1->next->next!=NULL) //пока у третьего после элемента (1) есть данные
{p2=p1->next; //переход элемента (2) к следующему элементу (1)
p3=p2->next; // переход элемента (3) к следующему элементу (2)
if(strcmp(p2->f.fam,p3->f.fam)>0)
{p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; // переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
else if(strcmp(p2->f.fam,p3->f.fam)==0)
if(strcmp(p2->f.im,p3->f.im)>0)
{
p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
else if(strcmp(p2->f.im,p3->f.im)==0)
if(strcmp(p2->f.ot,p3->f.ot)>0)
{
p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
p1=p1->next; //переход к следующему элементу (1)
}
} while(fl==1); //пока есть нарушения в алфавитном порядке
end1=p1->next; //переход конечного значения к следующему элементу (1)
}
void dinam:: outputstfile () //сохранение в файле списка student
{student*p; //указатель на список student
ofstream fout; //выходной поток
char file[l];
cout<<"imya faila:";
cin>>file; //ввод файла
fout.open(file); //открытие файла
if (fout==NULL) //если файл не создан,
{
cout<<"Fail ne sozdan"; //вывод сообщения об ошибке,
getch(); //задержка на экране
return; //возврат
}
cout<<"familiya "<<"imya "<<"otchestvo "<<"gruppa "<<"Kolichestvo ballov"<<endl;
p=beg1; //присвоение элементу начального значения
while(p!=NULL) //пока не закончится список student
{fout<<setw(14)<<setiosflags(ios::left)<<p->f.fam //запись в файл фамилий,
<<setw(11)<<setiosflags(ios::left)<<p->f.im //имен,
<<setw(15)<<setiosflags(ios::left)<<p->f.ot //отчеств,
<<setw(6)<<setiosflags(ios::left)<<p->gr //названия группы,
<<setw(10)<<setiosflags(ios::left)<<p->col<<endl; //количества баллов
p=p->next; //переход к следующему элементу
}
fout.close(); //закрытие файла
}
void dinam:: alfsortgr() //сортировка списка student по названию группы
{int fl; //в алфавитном порядке
student *p1,*p2,*p3; //указатели на список student
if(beg1==NULL||beg1->next==NULL) //если нет данных в начале списка student или в
//следующем элементе списка student
return; //возврат
do //выполнение действий:
{
fl=0;
p2=beg1; //присвоение элементу (2) начального значения
p3=p2->next; //переход элемента (3) к следующему элементу (2)
if(strcmp(p2->gr,p3->gr)>0) //если алфавитный порядок названий групп нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
else //в случае совпадения названий групп
if(strcmp(p2->gr,p3->gr)==0) //сортировка по фамилии
if(strcmp(p2->f.fam,p3->f.fam)>0) //если алфавитный порядок фамилий нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
else if(strcmp(p2->f.fam,p3->f.fam)==0) //в случае совпадения фамилий- сортировка по имени
if(strcmp(p2->f.im,p3->f.im)>0) // если алфавитный порядок имен нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
else if(strcmp(p2->f.im,p3->f.im)==0) //в случае совпадения имен сортировка по отчеству
if(strcmp(p2->f.ot,p3->f.ot)>0) // если алфавитный порядок отчеств нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
p1=beg1; //присвоение элементу (1) начального значения
while(p1->next->next!=NULL) //пока у третьего после элемента (1) есть данные
{p2=p1->next; //переход элемента (2) к следующему элементу (1)
p3=p2->next; //переход элемента (3) к следующему элементу (2)
if(strcmp(p2->gr,p3->gr)>0)
{
p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
else if(strcmp(p2->gr,p3->gr)==0)
if(strcmp(p2->f.fam,p3->f.fam)>0)
{p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
else if(strcmp(p2->f.fam,p3->f.fam)==0)
if(strcmp(p2->f.im,p3->f.im)>0)
{
p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
else if(strcmp(p2->f.im,p3->f.im)==0)
if(strcmp(p2->f.ot,p3->f.ot)>0)
{
p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
p1=p1->next; //переход к следующему элементу (1)
}
} while(fl==1); //пока есть нарушения в алфавитном порядке
end1=p1->next; //переход конечного значения к следующему элементу (1)
}
void dinam:: sortcol() //сортировка списка student по количеству баллов
{int fl; //в порядке убывания
student *p1,*p2,*p3; //указатели на список student
do //выполнение действий:
{
fl=0;
p2=beg1; //присвоение элементу (2) начального значения
p3=p2->next; //переход элемента (3) к следующему элементу (2)
if(p2->col<p3->col) //если порядок убывания количества баллов нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
if(p2->col==p3->col) //в случае совпадения количества баллов
//сортировка по названию группы
if(strcmp(p2->gr,p3->gr)>0) //если алфавитный порядок названий групп нарушен
{
p2->next=p3->next; //перестановка данных списка student
p3->next=p2;
beg1=p3;
fl=1;
}
p1=beg1; //присвоение элементу (1) начального значения
while(p1->next->next!=NULL) //пока у третьего после элемента (1) есть данные
{p2=p1->next; //переход элемента (2) к следующему элементу (1)
p3=p2->next; //переход элемента (3) к следующему элементу (2)
if(p2->col<p3->col)
{
p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
if(p2->col==p3->col)
if(strcmp(p2->gr,p3->gr)>0)
{
p2->next=p3->next; //переход следующего элемента (2) к следующему элементу (3)
p3->next=p2; //переход следующего элемента (3) к элементу (2)
p1->next=p3; //переход следующего элемента (1) к элементу (3)
fl=1;
}
p1=p1->next; //переход к следующему элементу (1)
}
}while(fl==1); //пока есть нарушения в порядке убывания
end1=p1->next; //переход конечного значения к следующему элементу (1)
}
void dinam::add() //добавление записи
{student*p; //указатель на список student
p=new student; //динамическое выделение памяти для списка student
if(p==NULL) //если нет памяти,
{
cout<<"net pamyati "; //вывод сообщения об ошибке на экран,
getch(); //задержка на экране
exit(1); //выход из программы
}
cout<<"Familiya:";
cin>>p->f.fam; //ввод фамилии,
cout<<"Imya:";
cin>>p->f.im; //ввод имени,
cout<<"Otchestvo:";
cin>>p->f.ot; //ввод отчества,
cout<<"Gruppa:";
cin>>p->gr; //ввод названия группы,
cout<<"Kolichestvo ballov:";
cin>>p->col; //ввод количества баллов
p->next=NULL; //опустошение следующего элемента
if (beg1==NULL) //если в начале списка student нет данных,
beg1=p; //присвоение ему значения элемента списка student
else //иначе присвоение
end1->next=p; //следующему конечному значения элемента
end1=p; //присвоение конечному значения элемента
m++;
}
student *dinam::find (fio name) // вспомогательная функция нахождения студентов
//по ФИО (*)
{student*p; //указатель на список student
p=beg1; //присвоение элементу начального значения
while (p!=NULL) //пока не закончится список student
{if (strcmp(p->f.fam,name.fam)==0; //если совпадение фамилий,
&&strcmp(p->f.im,name.im)==0; //имен,
&&strcmp(p->f.ot,name.ot)==0;) //отчеств,
return p; //возврат элемента
p=p->next; //переход к следующему элементу
}
return NULL; //возврат NULL
}
void dinam::deletefio() //удаление записи
{ student *p,*p0; //указатели на список student
fio t;
cout<<"Familiya:";
cin>>t.fam; //ввод фамилии,
cout<<"Imya:";
cin>>t.im; //ввод имени,
cout<<"Otchestvo:";
cin>>t.ot; //ввод отчества,
p0=find(t); //присвоение элементу (0) значения функции (*)
if (p0==NULL) //если студент с таким ФИО не найден,
{
cout<<t.fam<<" "<<t.im<<" "<<t.ot<<" ne naiden"; //вывод сообщения об ошибке на экран,
getch(); //задержка на экране,
return; //возврат
}
if (p0==beg1) ______ //если значение элемента равно начальному
{
beg1=beg1->next; //переход к следующему начальному значению
m--;
if (p0==end1) //если в этом списке был один узел,
end1=NULL; //опустошение конечного значения
delete p0; //удаление
}
else ______//иначе
{
p=beg1; //присвоение элементу начального значения
while(p->next!=p0) //пока следующий элемент не равен элементу (0)
p=p->next; //переход к следующему элементу
p->next=p0->next; //переход следующего элемента
m--; //к следующему элементу (0)
if (p0==end1) //если элемент (0) равен конечному значению
end1=p; //присвоение концу списка student значения
//элемента списка student