Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Выбор, размещение и задание свойств компонентов.




 Коды классов, функций и обработчиков событий

    Сохраните модуль главной формы под именем LR_6, а проект – под именем PR_LR_6.

Для размещения классов в проекте использован модуль, не связанный с формой. Чтобы создать такой модуль, нужно выполнить команду Файл/Новый/Другое… и открывшемся окне Новые элементы на странице Новый щелкнуть на пиктограмме Модуль. Модулю дано имя f_6. В заголовочном файле этого модуля f_6.hнаходятся объявления: структурного типа Node для данных заявки, класса data объекта – заявка и класса queue объекта - очередь заявок. В файле реализации модуля f_6.cpp – реализации классов (определения функций-элементов классов).

Заголовочный файлf_6.h модуля f_6 (без формы)

//---------------------------------------------------------------------------

#ifndef f_6H

#define f_6H

//---------------------------------------------------------------------------

//структура для данных

struct Node

{

char* name; //фамилия и.о.

char* model; //название устройства

char* work; //описание работ

int priority; //приоритет

};

//---------------------------------------------------------------------------

//класс - заявка

class data

{

public:

data(); //конструктор с умолчанием

data(const data &c); //конструктор копии

void set_dat(Node*); //установка данных

Node* get_dat(){return d;} //возвращает указатель на данные

data& operator=(const data& x);//перегруженная операция присваивания

~data(); //деструктор

private:

Node* d; //указатель на структуру с данными

};

//---------------------------------------------------------------------------

// класс - очередь заявок

class queue

{

public:

queue();  //конструктор

void insert(int i, Node*);//добавление i-той заявки в очередь

data del(); //выборка заявки из очереди

void queue_clear(); //удаление очереди

data get_mas_dat(int i){return dat[i];}//возврат i-той эаявки

void set_size(int s){size=s;}//задать количество заявок в очереди

int get_size(){return size;}//возврат количества заявок в очереди

~queue(); //деструктор

private:

data* dat; //указатель на данные (заявку)

int size; //количество заявок в очереди

};

//--------------------------------------------------------------------------

#endif

 

Файл реализацииf_6.cpp модуля f_6 (без формы)

//---------------------------------------------------------------------------

#pragma hdrstop

#include "f_6.h"

#include<string.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)

//---------------------------------------------------------------------------

//конструктор с умолчанием класса заявка

//примем, что количество символов

// в любом из полей заявки -  не более 50

data::data()

{

d=new Node;

d->name=new char[50];

d->model=new char[50];

d->work=new char[50];

d->priority=0;

}

//---------------------------------------------------------------------------

//конструктор копии класса заявка

data::data(const data& c)

{

d=new Node;

d->name = new char[50];

strcpy(d->name,c.d->name);

d->model = new char[50];

strcpy(d->model,c.d->model);

d->work = new char[50];

strcpy(d->work,c.d->work);

d->priority=c.d->priority;

}

//---------------------------------------------------------------------------

//установка данных

void data::set_dat(Node*pd)

{

strcpy(d->name,pd->name);

strcpy(d->model,pd->model);

strcpy(d->work,pd->work);

d->priority=pd->priority;

}

//---------------------------------------------------------------------------

//перегруженная операция присваивания

data& data::operator=(const data& x)

{

if(&x==this) return *this;

strcpy(d->name,x.d->name);

strcpy(d->model,x.d->model);

strcpy(d->work,x.d->work);

d->priority=x.d->priority;

return *this;

}

//---------------------------------------------------------------------------

//деструктор класса заявка

data::~data()

{

delete[]d->name;

delete[]d->model;

delete[]d->work;

delete d;

}

//---------------------------------------------------------------------------

//примем, что максимальное количество заявок в очереди - 20

const N=20;

//---------------------------------------------------------------------------

//конструктор класса очередь заявок

queue::queue()

{

dat= new data[N];

size=0;

}

//---------------------------------------------------------------------------

//добавление элемента в очередь

void queue::insert(int i, Node*pd)

{

dat[i].set_dat(pd);

 size++;

}

//---------------------------------------------------------------------------

//выборка элемента из очереди

data queue::del()

{

 int m=0;

 int pm=dat[0].get_dat()->priority;

 for(int i=1; i<size; i++)

if(pm<dat[i].get_dat()->priority)

{

  pm=dat[i].get_dat()->priority;

  m=i;

}

 data dm = dat[m];

 for(int i=m; i<size-1; i++) dat[i]=dat[i+1];

 size--;

 data dt;

 dat[size]=dt;

 return dm;

}

//---------------------------------------------------------------------------

//удаление очереди

void queue::queue_clear()

{

 if(!size) return;

 data dt=this->del();

 queue_clear();

}

//---------------------------------------------------------------------------

//деструктор класса очередь заявок

queue::~queue()

{

delete[]dat;

size=0;

}

//---------------------------------------------------------------------------

Замечания

1.В приложении используется композиция классов: в классе queue данное-элемент data* dat – указатель на объект класса data. При создании объекта класса queue вызову конструктора этого класса предшествуют вызовы конструкторов класса data N раз – по числу элементов в массиве для очереди.

2.Очередь формируется с начала массива; при выборке заявки из очереди последующие заявки сдвигаются к началу очереди. Следовательно, началом очереди является первый элемент массива (с индексом 0), а концом – элемент массива с индексом size-1, где size – количество заявок в очереди.

В предыдущей лабораторной работе было продемонстрировано использование диспетчера действийActionList. В данной работе продолжено использование этого компонента, вначале – в общем виде, затем – применительно к работе с очередью заявок с приоритетами в модели обслуживания клиентов компьютерного сервиса.

    Проектирование функциональной части интерфейса произвольного приложения с использованием диспетчера действийActionList состоит из  следующих шагов.

1.Проектирование начинается с составления списка действий, которые необходимо выполнять пользователю при работе с данным приложением и которые должны быть ему доступны через разделы меню, инструментальные панели, кнопки и другие элементы управления. Нетрудно видеть, что этот список должен содержать следующие действия: а) сохранить очередь в файле; б) вывести очередь из файла; в) добавить заявку в очередь; г) выбрать (удалить) заявку из очереди; д) уничтожить очередь; е) перейти от выполнения приложения к его проектированию. Кроме того, пользователь должен иметь возможность получить информацию о работе с приложением и его разработчике.

2.Для тех нестандартных действий, которые должны быть доступны из быстрых кнопок инструментальной панели, готовится список пиктограмм на кнопках в компоненте ImageList.

3.На главную форму переносится компонент диспетчер действийActionList. Он связывается с компонентом ImageList. В диспетчере действийActionListформируется список стандартных и нестандартных действий.

4.Каждому действию задается набор характеристик: Name (имя), Caption (надпись), ShortCut («горячие» клавиши), ImageIndex(номер изображения в ImageList), Hint (текст подсказки). Для нестандартных действий все эти характеристики записываются пользователем. Для стандартных действий они заносятся автоматически. Но если для характеристик стандартных действий нужен русский язык, то и они заносятся пользователем. Комбинации «горячих» клавиш также обычно требуют корректировки.

5.Записываются обработчики событий выполнения для всех нестандартных действий. Стандартные действия  обрабатываются автоматически и для многих из них достаточно задать некоторые свойства обработки. Но в общем случае и они требуют корректировки, а иногда надо писать обработчики событий выполнения и для стандартных действий.

6.На форму переносится компонент MainMenu1 – главное меню, связывается с ImageList, в компоненте формируется меню и в его разделах даются ссылки на действия, описанные в ActionList.

7.На форме создается инструментальная панель ToolBar. Панель связывается с ImageList, а в её кнопках даются ссылки на действия, описанные в ActionList.

Перейдем к проектированию приложения для работы с очередью приоритетов, используя  диспетчер действийActionList.

1.Перенесите на форму со страницы Win32 компонент ImageList1. Двойным щелчком на компоненте или щелчком правой кнопкой мыши и выбором команды контекстного меню Редактор ImageList перейдите в окно редактора списков изображений Form1->ImageList1 ImageList. В окне редактора можно добавить в список изображение, удалить изображение из списка, очистить весь список. Нажмите кнопку Добавить. Перейдите в окно файлов изображений командой …\Program Files\Common Files\Borland Shared\Images\Buttons. Выберите файл clear. Нажмите кнопку Открыть. На вопрос в окне Confirm ответьте утвердительно (Yes). В окне Образы выделите серое изображение щелчком мыши на нем и нажмите кнопку Удалить. В окне Образы останется яркое изображение с индексом 0. Снова нажмите кнопку Добавить. Повторите описанные выше действия для файлов delete, insert, help, npadwrit. Затем с помощью мыши расставьте изображения в окне Образы в следующем порядке: insert – 0, delete – 1, clear – 2, help – 3, npadwrit – 4. После всех этих действий нажмите кнопку Ок. Теперь все пять изображений с соответствующими индексами окажутся загруженными в компонент ImageList1.

2.Перенесите на форму со страницы Стандарт компонентActionList1и в его свойстве Images  сошлитесь на компонент ImageList1. Сделайте на компоненте ActionList1двойной щелчок, чтобы попасть в Редактор Действий (окно Редактирование Form1->ActionList1), позволяющий вводить и упорядочивать действия. Щелчок правой кнопкой мыши на окне редактирования или щелчок на маленькой кнопке со стрелкой вниз правее первой быстрой кнопки окна редактирования позволяет выбрать одну из команд: Новое действие или Новое стандартное действие. Первая из них относится к вводу нового действия любого типа. Введите Новое действие. При этом в колонке Категории: окна редактирования появится (Все действия), а в колонке Действия: появится Action1. Еще четырежды повторите ввод Новое действие, что вызовет в колонке Действия: появление Action2,Action3,Action4 и Action5.

3.Выделите Action1. В Инспекторе Объектов указанным ниже свойствам объекта действия Action1присвойте следующие значения: Caption –Добавить, Hint –добавить заявку, ImageIndex –0, Name –A_add, ShortCut –Ctrl+A. Для Action2: Caption –Выбрать, Hint –выбрать заявку, ImageIndex –1, Name –A_del, ShortCut –Ctrl+B. Для Action3: Caption –Очистить, Hint –очистить очередь, ImageIndex –2, Name –A_clr, ShortCut –Ctrl+C. Для Action4: Caption –О программе, ImageIndex –3, Name –A_help, ShortCut –Ctrl+D. Для Action5: Caption –О разработчике, ImageIndex –4, Name –A_wrt, ShortCut –Ctrl+E.

4.Для работы с файлами в среде Builder предусмотрены стандартные действия – вывести в файл и ввести из файла. Относятся они, например, к окнам редактирования и выполняют форматированный ввод-вывод. В нашем же случае нужно оперировать с информацией, связанной с полями структуры Node, что требует использования неформатированного ввода-вывода. Отметим далее, что поля структуры содержат ссылки на участки памяти, где находится подлежащая сохранению информация. Следовательно, в данном приложении не могут быть использованы стандартные действия с файлами. Поэтому в компонент ImageList1 добавьте изображения из файлов fileopen  и filesave, в компоненте ActionList1 добавьте двановых действия, дайте им имена  A_fopen и  A_fsaveи свяжите с соответствующими изображениями. В Инспекторе Объектов для A_fopen присвойте: Caption –Открыть,Hint –вывести очередь, ShortCut –Ctrl+ G. Подобным же образом для A_fsave:Caption –Сохранить,Hint –сохранить очередь, ShortCut –Ctrl+ F.

5.Теперь нужно перейти к разработке обработчиков событий для нестандартных действий. Но чтобы иметь возможность отладки обработчиков в процессе разработки, необходимо разместить на форме необходимые для этого компоненты. Поэтому закроем окно Редактирование Form1->ActionList1. Затем, руководствуясь рис.6.1 и содержимым файла LR_6.h (см. ниже), разместим на форме групповое окно GroupBox1 (страница Стандарт, CaptionДобавляемая заявка) с однострочными окнами редактирования LabeledEdit1..4 (страница Дополнительно),  метку Label1 (страница Стандарт, CaptionСписок заявок), LabeledEdit5 (EditLabel/CaptionКоличество заявок), GroupBox2 (CaptionВыбранная (удаляемая) заявка) с LabeledEdit6..9, таблицу строк StringGrid1 (страница Дополнительно). Перенесите также на форму (страница Диалоги) компоненты SaveDialog1 и OpenDialog1.

6.Сделайте на компоненте ActionList1двойной щелчок, чтобы попасть в Редактор Действий (окно Редактирование Form1->ActionList1). Чтобы перейти в  обработчик события выполнения какого-либо действия, например, A_add, сделайте на нем двойной щелчок. Имя обработчика - A_addExecute. Коды обработчиков представлены ниже (в файле реализации модуля LR_6 главной формы Form1).

7.Перенесите на форму компонент MainMenu1 (страница Стандарт). В свойствоImages компонента MainMenu1внесите ImageList1. Двойным щелчком на компоненте MainMenu1перейдите в окно Form1->MainMenu1 Конструктора Меню и создайте меню согласно рис.6.2.  В свойство Action разделов Открыть, Сохранить, Добавить, Выбрать, Очистить, О программе, О разработчике внесите соответственно значения A_fopen,  A_fsave, A_add, A_del, A_clr, A_help, A_wrt. Как показывает Инспектор Объектов, при этом в разделы меню переносятся свойства соответствующего объекта действия.

8.Со страницы Win32 перенесите на форму инструментальную панель - компонентToolBar. По умолчанию он расположится вверху, поскольку его свойство Align по умолчанию равно alTop. Установите Align=alNone, чтобы можно было сократить ширину и расположить ее под меню. Полезно также воспользоваться свойством Constraints. В свойство Hint впишите инструментальная панель, в свойство Imagesвнесите ImageList1, в ShowHint – true. Щелкните правой кнопкой мыши на компоненте ToolBar1 и из всплывшего меню выберите команду Новая кнопка. В свойство Actionкнопки внесите A_fopen, а в свойство ShowHint – true. Повторите эту команду еще для шести кнопок, внося в свойство Actionсоответственно A_fsave, A_add, A_del, A_clr, A_help, A_wrt, в свойство ShowHint – true. Отметим, что свойства и обработчики событий объекта действия будут перенесены на соответствующие кнопки инструментальной панели.

9.На рис.6.4 и рис.6.5 представлены дополнительные формы «О программе» и «О разработчике» с деревьями компонентов. Для включения в проект новой пустой формы достаточно выполнить команду Файл/Новый/Форма или нажать соответствующую быструю кнопку. Модулям дополнительных форм Form2и Form3даны соответственно имена LR_6_1и LR_6_2. На каждой из форм размещены компонент Memo1(страница Стандарт)и кнопка Button1с надписьюЗакрыть. Ниже представлены заголовочные файлы и файлы реализации модулей. Ввод текста в Memo осуществляется в окне Редактора строки списка, для перехода в которое нужно нажать кнопку с многоточием около свойства Lines в окне Инспектора Объектов.

 

Тестирование и использование приложения

1.Запустите приложение на выполнение, нажав быстрые кнопки Сохранить все и Запуск.

2.Составьте и выполните тесты, которые проверят правильность всех сообщений об ошибках.

3.Выполните тестирование, подобное представленному на рис.6.6.

4.Убедитесь в правильности сохранения очереди в файле.

5.Данные-элементы из закрытых частей классов перенесите в открытые части классов и затем внесите соответствующие изменения в код.

6. Выполните отладку приложения и полученный результат продемонстрируйте преподавателю.

Рис.6.1 – главная форма по окончании проектирования

         

Рис.6.2 – дерево компонентов                    Рис.6.3 – дерево классов

            главной формы                                          проекта

Рис.6.4 – форма «О программе» с деревом компонентов.

  

Рис.6.5 – форма «О разработчике» с деревом компонентов.

 

Рис.6.6 – главная форма с результатами тестирования

 

    Заголовочный файл модуля LR_6 главной формы Form1

 

//---------------------------------------------------------------------------

 

#ifndef LR_6H

#define LR_6H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

#include <Grids.hpp>

#include <ActnList.hpp>

#include <ComCtrls.hpp>

#include <ImgList.hpp>

#include <Menus.hpp>

#include <ToolWin.hpp>

#include <StdActns.hpp>

#include <Dialogs.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published:   // IDE-managed Components

   TLabeledEdit *LabeledEdit5;

   TLabel *Label1;

   TStringGrid *StringGrid1;

   TImageList *ImageList1;

   TActionList *ActionList1;

   TGroupBox *GroupBox1;

   TLabeledEdit *LabeledEdit1;

   TLabeledEdit *LabeledEdit2;

   TLabeledEdit *LabeledEdit3;

   TLabeledEdit *LabeledEdit4;

   TGroupBox *GroupBox2;

   TLabeledEdit *LabeledEdit6;

   TLabeledEdit *LabeledEdit7;

   TLabeledEdit *LabeledEdit8;

   TLabeledEdit *LabeledEdit9;

   TAction *A_add;

   TAction *A_del;

   TAction *A_clr;

   TAction *A_help;

   TAction *A_wrt;

   TMainMenu *MainMenu1;

   TMenuItem *N1;

   TMenuItem *N2;

   TMenuItem *N3;

   TMenuItem *N4;

   TMenuItem *N5;

   TMenuItem *N6;

   TMenuItem *N7;

   TMenuItem *N8;

   TMenuItem *N9;

   TMenuItem *N10;

   TMenuItem *N11;

   TToolBar *ToolBar1;

   TToolButton *ToolButton1;

   TToolButton *ToolButton2;

   TToolButton *ToolButton3;

   TToolButton *ToolButton4;

   TToolButton *ToolButton5;

   TToolButton *ToolButton6;

   TToolButton *ToolButton7;

   TOpenDialog *OpenDialog1;

   TSaveDialog *SaveDialog1;

   TAction *A_fsave;

   TAction *A_fopen;

   void __fastcall A_addExecute(TObject *Sender);

   void __fastcall FormCreate(TObject *Sender);

   void __fastcall A_delExecute(TObject *Sender);

   void __fastcall A_clrExecute(TObject *Sender);

   void __fastcall A_helpExecute(TObject *Sender);

   void __fastcall A_wrtExecute(TObject *Sender);

   void __fastcall N11Click(TObject *Sender);

   void __fastcall A_fsaveExecute(TObject *Sender);

   void __fastcall A_fopenExecute(TObject *Sender);

   void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

   private:   // User declarations

public:            // User declarations

   __fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

Файл реализации модуля LR_6 главной формы Form1

 

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

 

#include "LR_6.h"

#include "f_6.h"

#include<string.h>

#include "LR_6_1.h"

#include "LR_6_2.h"

#include<stdio.h>

#include<fstream.h>

#include<ctype.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

   : TForm(Owner)

{

}

//---------------------------------------------------------------------------

queue q;

void __fastcall TForm1::A_addExecute(TObject *Sender)

{

LabeledEdit6->Text="";

LabeledEdit7->Text="";

  LabeledEdit9->Text="";

LabeledEdit8->Text="";

if(LabeledEdit1->Text=="")

  {MessageBox(NULL,"Введите Фамилия И.О.!","Ошибка",0);

   LabeledEdit1->SetFocus();

   return;

  }

if(LabeledEdit2->Text=="")

  {MessageBox(NULL,"Введите Устройство!","Ошибка",0);

   LabeledEdit2->SetFocus();

   return;

  }

if(LabeledEdit3->Text==""||!isdigit(LabeledEdit3->Text[1]))

  {MessageBox(NULL,"Введите Приоритет!","Ошибка",0);

   LabeledEdit3->SetFocus();

   return;

  }

if(LabeledEdit4->Text=="")

  {MessageBox(NULL,"Введите Описание работ!","Ошибка",0);

   LabeledEdit4->SetFocus();

   return;

  }

LabeledEdit5->Text=IntToStr(q.get_size());

Node* pd;

pd=new Node;

pd->name = new char[50];

strcpy(pd->name,LabeledEdit1->Text.c_str());

pd->model = new char[50];

strcpy(pd->model,LabeledEdit2->Text.c_str());

pd->work = new char[50];

strcpy(pd->work,LabeledEdit4->Text.c_str());

pd->priority=StrToInt(LabeledEdit3->Text.c_str());

q.insert(q.get_size(),pd);

 

LabeledEdit5->Text=IntToStr(q.get_size());

LabeledEdit1->Clear();

LabeledEdit2->Clear();

LabeledEdit3->Clear();

LabeledEdit4->Clear();

LabeledEdit1->SetFocus();

StringGrid1->RowCount++;

int i=q.get_size()-1;

StringGrid1->Cells[0][i+1]=

        (AnsiString)(q.get_mas_dat(i).get_dat()->name);

StringGrid1->Cells[1][i+1]=

        (AnsiString)(q.get_mas_dat(i).get_dat()->model);

StringGrid1->Cells[2][i+1]=

        (AnsiString)(q.get_mas_dat(i).get_dat()->work);

StringGrid1->Cells[3][i+1]=

        IntToStr(q.get_mas_dat(i).get_dat()->priority);

 

delete[]pd->name;

delete[]pd->model;

delete[]pd->work;

delete pd;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

{

LabeledEdit5->Text="0";

StringGrid1->FixedRows=1;

StringGrid1->RowCount=1;

StringGrid1->FixedCols=0;

StringGrid1->ColCount=4;

StringGrid1->Cells[0][0]="Фамилия И.О.";

StringGrid1->Cells[1][0]="Устройство";

StringGrid1->Cells[2][0]="Описание работ";

StringGrid1->Cells[3][0]="Приоритет";

}

//---------------------------------------------------------------------------

void __fastcall TForm1::A_delExecute(TObject *Sender)

{

LabeledEdit6->Clear();

LabeledEdit7->Clear();

LabeledEdit9->Clear();

LabeledEdit8->Clear();

if(!(q.get_size()))

{

  MessageBox(NULL,"Очередь пуста!","",0);

  return;

}

data d=q.del();

LabeledEdit5->Text=IntToStr(q.get_size());

LabeledEdit6->Text=(AnsiString)d.get_dat()->name;

LabeledEdit7->Text=(AnsiString)d.get_dat()->model;

LabeledEdit9->Text=(AnsiString)d.get_dat()->work;

LabeledEdit8->Text=IntToStr(d.get_dat()->priority);

int i=0;

while(i<q.get_size())

{

StringGrid1->Cells[0][i+1]=

     (AnsiString)(q.get_mas_dat(i).get_dat()->name);

StringGrid1->Cells[1][i+1]=

     (AnsiString)(q.get_mas_dat(i).get_dat()->model);

StringGrid1->Cells[2][i+1]=

     (AnsiString)(q.get_mas_dat(i).get_dat()->work);

StringGrid1->Cells[3][i+1]=

     IntToStr(q.get_mas_dat(i).get_dat()->priority);

i++;

}

StringGrid1->RowCount--;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::A_clrExecute(TObject *Sender)

{

if(!(q.get_size()))

{

  MessageBox(NULL,"Очередь пуста!","",0);

  return;

}

q.queue_clear();

StringGrid1->RowCount=1;

LabeledEdit1->Clear();

LabeledEdit2->Clear();

LabeledEdit3->Clear();

LabeledEdit4->Clear();

LabeledEdit5->Text=IntToStr(q.get_size());

LabeledEdit6->Clear();

LabeledEdit7->Clear();

LabeledEdit8->Clear();

LabeledEdit1->SetFocus();

if(!(q.get_size()))

{

     MessageBox(NULL,"Очередь уничтожена!","",0);

  return;

}

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::A_helpExecute(TObject *Sender)

{

Form1->Enabled=false;

Form2->Show();

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::A_wrtExecute(TObject *Sender)

{

Form1->Enabled=false;

Form3->Show();

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::N11Click(TObject *Sender)

{

 if(q.get_size()>0)

  q.queue_clear();

 Close();

}

//---------------------------------------------------------------------------

 

AnsiString fn;

//---------------------------------------------------------------------------

 

void __fastcall TForm1::A_fsaveExecute(TObject *Sender)

{

if(SaveDialog1->Execute())

   {

    fn=SaveDialog1->FileName;

    ofstream outfile(fn.c_str(),ios::out);

    if(!outfile)

      {

       MessageBox(NULL,"Файл не удается создать!","Ошибка",0);

       return;

      }

    int s=q.get_size();

    outfile.write((char*)&s,sizeof(s));

    for(int i=0; i<s; i++)

    {

    outfile.write((char*)q.get_mas_dat(i).get_dat()->name,50);

    outfile.write((char*)q.get_mas_dat(i).get_dat()->model,50);

    outfile.write((char*)q.get_mas_dat(i).get_dat()->work,50);

    outfile.write((char*)&(q.get_mas_dat(i).get_dat()->priority),sizeof(int));

 

    }

    outfile.close();

  }

}

//---------------------------------------------------------------------------

void __fastcall TForm1::A_fopenExecute(TObject *Sender)

{

if(q.get_size()>0)

  q.queue_clear();

StringGrid1->RowCount=1;

LabeledEdit5->Text="";

if(OpenDialog1->Execute())

{

fn=OpenDialog1->FileName;

ifstream infile(fn.c_str(),ios::in);

   if(!infile)

  {

   MessageBox(NULL,"Файл не удается открыть!","Ошибка",0);

   return;

  }

int s;

infile.read((char*)&s,sizeof(s));

 

for(int i=0; i<s; i++)

  {

   Node*pd=new Node;

   pd->name=new char[50];

   pd->model=new char[50];

   pd->work=new char[50];

    infile.read((char*)pd->name,50);

    infile.read((char*)pd->model,50);

    infile.read((char*)pd->work,50);

    infile.read((char*)&(pd->priority),sizeof(int));

    q.insert(i,pd);

   StringGrid1->RowCount++;

   StringGrid1->Cells[0][i+1]=

      (AnsiString)(q.get_mas_dat(i).get_dat()->name);

   StringGrid1->Cells[1][i+1]=

      (AnsiString)(q.get_mas_dat(i).get_dat()->model);

   StringGrid1->Cells[2][i+1]=

      (AnsiString)(q.get_mas_dat(i).get_dat()->work);

   StringGrid1->Cells[3][i+1]=

      IntToStr(q.get_mas_dat(i).get_dat()->priority);

   delete[]pd->name;

   delete[]pd->model;

   delete[]pd->work;

   delete pd;

  }

q.set_size(s);

LabeledEdit5->Text=IntToStr(q.get_size());

if(!q.get_size())

  {

      MessageBox(NULL,"Очередь пуста!","",0);

    return;

 }

infile.close();

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

if(q.get_size()>0)

  q.queue_clear();       

}

//---------------------------------------------------------------------------

Заголовочный файл модуля LR_6_1 формы Form2

//---------------------------------------------------------------------------

#ifndef LR_6_1H

#define LR_6_1H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

//---------------------------------------------------------------------------

class TForm2 : public TForm

{

__published:   // IDE-managed Components

   TMemo *Memo1;

   TButton *Button1;

   void __fastcall Button1Click(TObject *Sender);

   void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

private:  // User declarations

public:            // User declarations

   __fastcall TForm2(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm2 *Form2;

//---------------------------------------------------------------------------

#endif

 

Файл реализации модуля LR_6_1 формы Form2

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

 

#include "LR_6_1.h"

#include "LR_6.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm2 *Form2;

//---------------------------------------------------------------------------

__fastcall TForm2::TForm2(TComponent* Owner)

   : TForm(Owner)

{

}

//---------------------------------------------------------------------------

 

void __fastcall TForm2::Button1Click(TObject *Sender)

{

Close();       

}

//---------------------------------------------------------------------------

void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)

{

Form1->Enabled=true;

}

//---------------------------------------------------------------------------

Заголовочный файл модуля LR_6_2 формы Form3.

//---------------------------------------------------------------------------

#ifndef LR_6_2H

#define LR_6_2H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

//---------------------------------------------------------------------------

class TForm3 : public TForm

{

__published:   // IDE-managed Components

   TMemo *Memo1;

   TButton *Button1;

   void __fastcall Button1Click(TObject *Sender);

   void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

private:  // User declarations

public:            // User declarations

   __fastcall TForm3(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm3 *Form3;

//---------------------------------------------------------------------------

#endif

 

Файл реализации модуля LR_6_2 формы Form3

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

 

#include "LR_6_2.h"

#include "LR_6.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm3 *Form3;

//---------------------------------------------------------------------------

__fastcall TForm3::TForm3(TComponent* Owner)

   : TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm3::Button1Click(TObject *Sender)

{

Close();       

}

//---------------------------------------------------------------------------

void __fastcall TForm3::FormClose(TObject *Sender, TCloseAction &Action)

{

Form1->Enabled=true;

}

//---------------------------------------------------------------------------

Контрольные вопросы

1.Внесите комментарии в файл LR_6.cpp.

2.Внесите комментарии в функции-элементы класса data в файле f_6.cpp.

3.Внесите комментарии в функции-элементы класса queue в файле f_6.cpp.

4.Как реализовать условие полной очереди?

5.Укажите в коде точки вызова конструктора с умолчанием класса data.

6.Где и как нужно изменить код, чтобы вывести количество вызовов конструктора с умолчанием класса data?

7.Укажите в коде точки вызова конструктора копии класса data.

8.Где и как нужно изменить код, чтобы вывести количество вызовов конструктора копии класса data?

9.Укажите в коде точки вызова конструктора класса queue.

10.Где и как нужно изменить код, чтобы вывести количество вызовов конструктора класса queue?

11.Укажите в коде точки вызова деструктора класса queue.

12.Где и как нужно изменить код, чтобы вывести количество вызовов деструктора класса queue?

13.Укажите в коде точки вызова деструктора класса data.

14.Где и как нужно изменить код, чтобы вывести количество вызовов деструктора класса data?

15.Укажите в коде точки вызова перегруженной операции присваивания класса data.

16.Где и как нужно изменить код, чтобы вывести количество вызовов перегруженной операции присваивания класса data?

17.Как создается объект класса data?

18.Как создается копия объекта класса data?

19.Как создается объект класса queue?

20.Как уничтожается объект класса data?

21.Как уничтожается объект класса queue?

22.Как создается очередь?

23.Изобразите структуру очереди в лабораторной работе.

24.Что является началом и что – концом очереди?

25.Как выбирается заявка из очереди?

26.Как уничтожается очередь?

27.Как очередь выводится в файл?

28.Как очередь вводится из файла?

29.Расскажите о способах реализации очередей.

30.Расскажите о порядке использования компонента ActionList.

31.Как связать MainMenuс ActionList?

32.Как связать ImageListс ActionList, с MainMenu, с ToolBar?

33.Как связать ToolBar с ActionList?

 

Задания (стеки, очереди)

1. В файле находится текст, в котором используются скобки трех типов: ( ), [ ], { }. Используя стек, проверить, соблюден ли баланс скобок в тексте.

2.Используя очередь, установить, сбалансирован ли по круглым скобкам записанный в файле текст. Требуется для каждой пары соответствующих открывающей и закрывающей скобок напечатать номера их позиций в тексте, упорядочив пары номеров по возрастанию номеров позиций: а) закрывающих скобок (например, для текста a+(45-f(x)*(b-c)) надо напечатать: 8 10; 12 16; 3 17); б) открывающих скобок (например, для текста a+(45-f(x)*(b-c)) надо напечатать: 3 17; 8 10; 12 16);

3. Используя стек, проверить, является ли содержимое текстового файла правильной записью формулы следующего вида: <формула>::=<терм> | <терм>+<формула> | <терм>-<формула>, <терм>::=<имя> | (<формула>), <имя>::=x | y | z.

4.В текстовом файле записана без ошибок формула Ф следующего вида: <Ф>::=<цифра> | M(<Ф>,<Ф >) | m(<Ф>,<Ф >), <цифра>::=0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9. (M обозначает функцию max, а m - функцию min.). Используя стек, вычислить как целое число значение данной формулы. Например: M(5,m(6,8))=6.

5.В текстовом файле записано без ошибок логическое выражение ЛВ следующего вида: <ЛВ>::=true | false | !<ЛВ> | <ЛВ>&&<ЛВ> | <ЛВ>||<ЛВ>. Используя стек, вычислить значение этого выражения с учетом приоритета операций.

6.Написать и протестировать функции включения, удаления и чтения очередного элемента стека объемом  n  элементов. В случае невозможности включения (переполнение стека), удаления из пустого стека выставлять флаг.

7.Для организации вычисления значения выражения удобнее вместо обычной (инфиксной) записи построить постфиксную (или польскую инверсную) запись - ПОЛИЗ. При вычислениях выражения, записанного в ПОЛИЗе, операции выполняются в том порядке, в котором они встречаются при просмотре выражения слева направо; поэтому отпадает необходимость использования скобок и многократного сканирования выражения из-за различного старшинства операций. Например, выражению 2+3*4 соответствует ПОЛИЗ 234*+, а выражению (a+(b-c)-d)*(e+f /d) - запись abc-+d-efd/+*. Используя стек, вычислить как целое число значение выражения, записанного в ПОЛИЗе.

8. Используя стек, выражение, записанное в ПОЛИЗе, перевести в инфиксную форму и распечатать (см. п.7).

9.С использованием структуры стек переписать содержимое текстового файла, разделенного на строки, в другой файл. Следует перенести в конец каждой строки все входящие в нее цифры в обратном порядке.

10.С использованием структуры очередь за один просмотр файла, содержащего целые числа, распечатать файл в следующем виде: сначала - все числа, меньшие A, затем - все числа из [A,B], потом - все остальные числа.

11.Пусть имеется ЭВМ, у которой один регистр и шесть команд:                                   

          LD A    загрузить A в регистр;

          ST A     запомнить содержимое регистра в A;

              AD A    сложить содержимое регистра с A;

         SB A     вычесть A из содержимого регистра;

          ML A    умножить содержимое регистра на A;

         DV A     разделить содержимое регистра на A.

Напечатать последовательность машинных команд, необходимых для вычисления выражения, задаваемого в постфиксной форме. Выражение может состоять из однобуквенных операндов и знаков операций сложения, вычитания, умножения и деления. В качестве рабочих предлагается использовать переменные вида Tn.

Например, выражению ABC*+DE-/  будет соответствовать следующая последовательность команд :

                                              LD               B

                                              ML              С

                                              AD               A

                                              ST               T1

                                              LD               D

                                              SB               E

                                              ST                T2

                                              LD               T1

                                             DV                T2

                                              ST                T1

12.Для проверки того, является ли текст палиндромом, считать строку текста, помещая каждый непустой символ и в очередь, и в стек.

13.Массив может использоваться для сохранения двух стеков, один(S1), растущий (в направлении индекса) с левого конца, второй(S2), уменьшающийся с правого конца. Проверить, пуст ли S1, пуст ли S2, полон ли S1, полон ли S2; считать последовательность из целых чисел, помещая все четные в один стек, а нечетные – в другой. Вывести содержимое каждого стека.

14.Написать программу - модель очереди в супермаркете.

Покупатели появляются случайным образом в интервале времени от 1 до 4 минут. Обслуживается очередной покупатель также случайным образом в интервале времени от 1 до 4 минут. При несбалансированных скоростях появления и обслуживания очередь может бесконечно расти. Запустить модель очереди при условии 12-часового рабочего дня, используя следующий алгоритм: 1) взять случайное целое число в диапазоне от 1 до 4, означающее минуту появления первого покупателя; 2) в момент появления первого покупателя: определить время обслуживания (случайное целое число от 1 до 4 минут); начать обслуживание покупателя; спланировать время появления следующего покупателя (добавить к текущему времени случайное целое в диапазоне от 1 до 4); 3) для каждой минуты дня: если появился следующий покупатель, то поставить его в очередь, спланировать время появления следующего покупателя; если обслужен очередной покупатель, то исключить из очереди следующего покупателя, определить время его обслуживания.

Ответить на следующие вопросы: а) какое максимальное число покупателей было в очереди? б) каково максимальное время ожидания для покупателя? в) что происходит, если интервалы времени изменить с 1 - 4 минут до 1 - 3 минут?

15.С помощью стека реализовать преобразование десятичных чисел в числа с задаваемым основанием.

16.Вычислить значение инфиксного выражения, используя два стека.

17.Вычислить значение постфиксного выражения, используя один стек.

18.Используя очередь, реализовать модель танцев. По мере того, как мужчины и женщины входят в танцзал, мужчины выстраиваются в один ряд, женщины – в другой. Когда начинается танец, партнеры выбираются по одному из начала каждого ряда. Если в рядах количество людей неодинаковое, лишний человек должен ждать следующего танца.

Программа получает имена мужчин и женщин из файла (количество – случайное) и организуются очереди. Партнеры образуются удалением их из каждой очереди. Этот процесс останавливается, когда какая-либо очередь становится пустой. Если есть ожидающие люди, указать имя первого человека, который будет участвовать в следующем танце.

19.Написать программу для поразрядной сортировки данных, суть которой состоит в следующем. Пусть элементы массива содержат числа из двух цифр в диапазоне 00 – 99. Для сортировки используются 10 бункеров с номерами 0-9. Для сортировки нужны два прохода: сначала для обработки по позициям единиц, а затем – десятков. Если, например, массив содержит числа 91 46 85 15 92 35 31 22, то в первом проходе числа помещаются в бункеры в следующем порядке: в бункер 1 – 91,31, в бункер 2 – 92,22, в бункер 5 – 85,15,35, в бункер 6 – 46. Выбор из бункеров в порядке от 0 до 9 даёт результат первого прохода: 91 31 92 22 85 15 35 46. Во втором проходе распределение  по бункерам таково: 1 – 15, 2 – 22, 3 – 31,35, 4 – 46, 8 – 85, 9 – 91,92. После выбора из бункеров получается последовательность: 15 22 31 35 46 85 91 92.

20.Стек может использоваться для распознавания определенных типов образов. Рассмотрим образец string1#string2, где строки не содержат #  и string2 должна быть обратна string1. Например, строка “123@~a#a~@321” совпадает с образцом, а строка “a2qd#dq3a” – нет. Написать программу, которая считывает из файла заданное количество строк и указывает, совпадает или нет каждая строка с образцом.

21.Используя очередь, реализовать модель кольцевого буфера ёмкостью 1024 вещественных числа. Программа должна инициализировать буфер, добавлять/удалять элемент, определять количество свободного/занятого пространства в буфере.

22.Реализовать круговую модель очереди. При удалении элемента из круговой очереди не нужен сдвиг оставшихся элементов, - достаточно переопределить значение переменной, указывающей на начало очереди. Добавление элемента требует переопределения значения другой переменной, адресующей конец очереди. Отметим, что в круговой очереди последний элемент связан либо с первым свободным элементом, либо с началом очереди. Ещё одна переменная поддерживает запись количества элементов в очереди; равенство этой переменной максимальному значению означает, что очередь заполнена. Написать программу, реализующую модель круговой очереди.

23.Составить программу, отыскивающую проход по лабиринту. Лабиринт представляется в виде матрицы, состоящей из квадратов. Каждый квадрат либо открыт, либо закрыт. Вход в закрытый квадрат запрещен. Если квадрат открыт, то вход в него возможен со стороны, но не с угла. Каждый квадрат определяется его координатами в матрице. Программа находит проход через лабиринт, двигаясь от заданного входа. После отыскания прохода программа выводит найденный путь в виде координат квадратов. Для хранения пути использовать стек.

24.Гаражная стоянка имеет одну стояночную полосу, причем въезд и выезд находятся в одном конце полосы. Если владелец автомашины приходит забрать свой автомобиль, который не является ближайшим к выходу, то все автомашины, загораживающие проезд, удаляются, машина данного владельца выводится со стоянки, а другие машины возвращаются на стоянку в исходном порядке. Написать программу, которая моделирует процесс прибытия и отъезда машин. Прибытие или отъезд автомашины задается командной строкой, которая содержит признак прибытия или отъезда и номер машины. Программа должна выводить сообщение при прибытии или въезде любой машины. При выезде автомашины со стоянки сообщение должно содержать число раз, которое машина удалялась со стоянки для обеспечения выезда других автомобилей.

25.Задача “ханойские башни” относится к классическим задачам и состоит в том, чтобы переместить стопку дисков с одного шпиля на другой. Начальная стопка имеет n дисков, нанизанных на один шпиль так, что их размеры последовательно уменьшаются к вершине. Условия перемещения: при каждом перемещении можно брать только один диск, и больший диск никогда не должен находиться над меньшим диском. Третий шпиль даёт возможность временного размещения дисков. Написать программу, которая позволяет установить зависимость количества перемещений от величины n.

26.Очередь для моделирования Т-образного сортировочного узла на железной дороге. Программа должна разделять на два направления состав, состоящий из вагонов двух типов (на каждое направление формируется состав из вагонов одного типа). Предусмотреть возможность формирования состава из файла и с клавиатуры.

27.Стек для моделирования Т-образного сортировочного узла на железной дороге. Программа должна разделять на два направления состав, состоящий из вагонов двух типов (на каждое направление формируется состав из вагонов одного типа). Предусмотреть возможность формирования состава из файла и с клавиатуры.

28.Написать программу, реализующую стеки на основе массива и на основе списка.

29.Использовать стек для вывода по задаваемому основанию вводимых чисел с произвольным основанием.

30.Реализовать постфиксный калькулятор на основе стека.

 


ЛАБОРАТОРНАЯ  РАБОТА  7

ДВУНАПРАВЛЕННЫЙ НЕОДНОРОДНЫЙ СПИСОК

С ОДНОРОДНЫМИ ПОДСПИСКАМИ

 

Введение

        Список является структурой хранения данных. Если список – динамическая структура данных, то в простейшем случае – это линейный связный список, состоящий из элементов (узлов), каждый из которых содержит как собственные данные, так и одну (или две) ссылки на следующий (и предыдущий) узел. Принципиальным преимуществом перед массивом является структурная гибкость: порядок элементов связного списка может не совпадать с порядком расположения элементов данных в памяти компьютера, количество элементов не нужно задавать заранее, порядок обхода списка всегда явно задается его внутренними связями.

Существует несколько разновидностей связного списка. Однонаправленный список – каждый элемент содержит данные и указатель на следующий элемент. В кольцевом списке последний элемент содержит указатель на первый элемент. Двунаправленный связный список – в этом списке каждый элемент содержит указатели как на следующий, так и на предыдущий элементы. В таком списке, в отличие от однонаправленного списка, можно перемещаться в двух направлениях. В однородном списке все элементы имеют один и тот же тип. Неоднородный (гетерогенный) список имеет разнотипные элементы, причем  однотипные  элементы в нем объединяют в однородные подсписки.

    Целью данной лабораторной работе является изучение приложения для работы с двунаправленным неоднородным списком с однородными подсписками, представленным на рис.7.1. Из структуры списка видно, что основной список состоит из взаимосвязанных первых элементов подсписков. Ссылка на начало списка находится в указателе first, а ссылка на конец списка – в указателе last.

Классы

Примем, что разнотипными элементами в списке являются объекты разных классов. Общее для них состоит в том, что они связаны друг с другом указателями. Поэтому введем базовый класс с указателями на этот же класс:

class link

{

public:

link* prev; // указатель на предыдущий элемент основного списка

 link* next; // указатель на следующий элемент основного списка

link* down; // указатель на следующий элемент подсписка

types type;

link(){prev=next=down=0;}//конструктор с умолчанием

};

 

Рис.7.1 – структура двунаправленного неоднородного списка

с n однородными подсписками

 

    Примем также, что список предназначен для контроля товаров в спортивноммагазине, группируемых в подсписки по наименованию и фирме-производителю. Пусть товарами будут «велосипеды» и «роликовые коньки». Тогда в списке они должны быть представлены элементами подсписков - объектами соответствующих классов. Эти классы будут производными классами от базового класса. Для определения объекта производного класса в базовый класс введен элемент  type типа-перечисление: enum types{Roll, Bike}.

 

//---------------------------------------------------------------------------

//производный класс для элемента подсписка - роликовые коньки

class TRoll:public link

{

  public:

char* date; //дата поступления

char* comp; //производитель

int diam; //диаметр колес (в мм)

int count; //количество (штук)

TRoll(); //конструктор

~TRoll(); //деструктор

};

//--------------------------------------------------------------------------

//производный класс для элемента подсписка - велосипед

class TBike:public link

{

  public:

char* date; //дата поступления

char* comp; //производитель

int diam; //диаметр колес (в мм)

int count; //количество (штук)

float weight; //вес (в кг)

  int speeds; //количество скоростей

TBike(); //конструктор

~TBike(); //деструктор

};

//--------------------------------------------------------------------------

    При создании объектов классов TRoll и TBike – элементов подсписков – в конструкторах этих классов в данное-элемент базового класса type подставляется значение (Roll, Bike), позволяющее идентифицировать создаваемые объекты. Доступ к type – через указатель на базовый класс link.

    Теперь создадим класс, объединяющий созданные выше классы для элементов подсписков и предназначенный для создания объекта «список».

 

//--------------------------------------------------------------------------

//класс для списка

class list

{

public:

link* first; //указатель на начало списка

link* last; //указатель на конец списка

int count_dsp; //количество подсписков

  int count_elem_sp; //количество элементов в списке

bool is_empty; //флаг "список пуст"

list(); //конструктор

~list(); //деструктор

void append_bike(TBike*);//добавление элемента-велосипеда в список

void append_roll(TRoll*);//добавление элемента-роликовые коньки

                          // в список

void del(int); //удаление элемента из списка

void out_list(); //вывод списка в таблицу

void clear_down(int); //удаление подсписка из списка

void clear(); //уничтожение списка

};

//--------------------------------------------------------------------------

    Комментарии в объявлении последнего класса содержат перечень большинства операций при работе со списком. Следует отметить, что все элементы списка имеют по три указателя (prev, next, down), но только в элементах основной части списка, т.е. в первых элементах подсписков, используются все три указателя, а в остальных элементах подсписков – один указатель (down). При удалении первого элемента подсписка на его место ставится второй, что потребует в нем инициализации указателей prev и next адресами предыдущего и последующего элементов соответственно в основной части списка.

 

Проектирование приложения.










Последнее изменение этой страницы: 2018-05-29; просмотров: 186.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...