1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
| type
//Указатель на элемент очереди.
TPElem = ^TElem;
//Элемент очереди.
TElem = record
Data : Integer;
PNext : TPElem;
end;
//Очередь.
TQueue = record
PFirst, PLast : TPElem;
end;
//Добавление элемента в конец очереди.
procedure QueuePush(var aQueue : TQueue; var aPElem : TPElem);
begin
if aPElem = nil then Exit;
aPElem^.PNext := nil;
if aQueue.PFirst = nil then
aQueue.PFirst := aPElem
else
aQueue.PLast^.PNext := aPElem
;
aQueue.PLast := aPElem;
end;
//Изъятие элемента из начала очереди.
function QueuePop(var aQueue : TQueue; var aPElem : TPElem) : Boolean;
begin
Result := False;
if aQueue.PFirst = nil then Exit;
aPElem := aQueue.PFirst;
aQueue.PFirst := aPElem^.PNext;
if aQueue.PFirst = nil then aQueue.PLast := nil;
Result := True;
end;
//Удаление очереди из памяти (очистка очереди).
procedure QueueFree(var aQueue : TQueue);
var
PDel : TPElem;
begin
while QueuePop(aQueue, PDel) do Dispose(PDel);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
F : TextFile;
Q1, Q2 : TQueue;
PElem : TPElem;
i, Num : Integer;
S, S2 : String;
Od : TOpenDialog;
begin
Od := OpenDialog1;
if Od.InitialDir = '' then
Od.InitialDir := ExtractFilePath( ParamStr(0) )
;
if not Od.Execute then Exit;
Memo1.Lines.Add('--------------------------------------------------');
Memo1.Lines.Add('Файл: "' + Od.FileName + '"');
if not FileExists(Od.FileName) then begin
Memo1.Lines.Add(
'Файл с заданным именем не найден. Действие отменено.'
);
Exit;
end;
//Инициализация очередей.
Q1.PFirst := nil;
Q1.PLast := nil;
Q2.PFirst := nil;
Q2.PLast := nil;
//Значение нового элемента, который должен быть добавлен
//в начало очереди.
Num := StrToInt(Edit1.Text);
Memo1.Lines.Add(
'В начало очереди должен быть добавлен элемент: '
+ IntToStr(Num)
);
//Читем элементы из файла и записываем их в первую очередь.
//Одновременно, готовим строку для распечатки.
AssignFile(F, Od.FileName);
Reset(F);
i := 0;
S2 := '';
while not Eof(F) do begin
Readln(F, S);
if S = '' then Continue; //Если строка пустая - пропускаем итерацию.
New(PElem);
PElem^.Data := StrToInt(S);
QueuePush(Q1, PElem);
//Для распечатки.
Inc(i);
if S2 <> '' then S2 := S2 + ', ';
S2 := S2 + IntToStr(i) + ':' + IntToStr(PElem^.Data); //Индекс:Значение.
end;
//Закрываем файл.
CloseFile(F);
//Если в файле нет сведений - выходим.
if Q1.PFirst = nil then begin
Memo1.Lines.Add('Файл пуст. Действие отменено.');
Exit;
end;
//Распечатка первой очереди.
Memo1.Lines.Add('Исходная очередь:');
Memo1.Lines.Add(S2);
//Решение задачи.
//В качестве первого элемента во вторую очередь добавляем
//заданный пользователем элемент.
New(PElem);
PElem^.Data := Num;
QueuePush(Q2, PElem);
//Переливаем элементы из первой очереди во вторую.
//При этом, первая очередь окажется пустой.
while QueuePop(Q1, PElem) do QueuePush(Q2, PElem);
//Распечатка второй очереди. При этом вторая очередь окажется
//пустой. Каждый элемент, изъятый из очереди мы должны
//удалить из памяти.
Memo1.Lines.Add('Очередь после вставки в начало нового элемента:');
i := 0;
S2 := '';
while QueuePop(Q2, PElem) do begin
Inc(i);
if i > 1 then S2 := S2 + ', ';
S2 := S2 + IntToStr(i) + ':' + IntToStr(PElem^.Data); //Индекс:Значение.
Dispose(PElem); //Удаление элемента из памяти.
end;
Memo1.Lines.Add(S2);
//Удаление очередей из памяти. Не смотря на то, что в данный момент
//обе очереди и так уже пустые, этот шаг необходим для надёжности
//кода на случай, если в будущем алгоритм будет изменён.
QueueFree(Q1);
QueueFree(Q2);
end; |