
alg-01.ppt
- Количество слайдов: 59
Эффективные алгоритмы Хартиков Сергей Михайлович
“Разработка эффективных алгоритмов” + “Рекурсивная реализация алгоритмов” + “Технология программирования” = “Эффективные алгоритмы”
Free Pascal www. freepascal. org
1 1 1 2 2 4 4 8 8 Byte Short. Int Boolean Word Integer Longint Cardinal Int 64 Qword 0. . 255 -128. . +127 False(0). . True(1) 0. . +65 535 -32 768. . +32 767 - 2 * 109. . + 2 * 109 0. . 4 * 109 - 1019. . + 1019 0. . 2 * 1019 4/8 4 8 10 8 8 Real Single Double Extended Comp Currency platform dependant 1. 5 E-45. . 3. 4 E 38 (7 -8 5. 0 E-324. . 1. 7 E 308 (15 -16 1. 9 E-4932. . 1. 1 E 4932 (19 -20 -2 E 64+1. . 2 E 63 -1 (19 -20 +/-922337203685477. 5808/7 digits)
var x, y, z : Byte; a, b, c : Word; begin … z : = x + y; c : = a + b; …
Тип данных = Интерпретация содержимого памяти + Совокупность процедур обработки
Вычисление выражений var x, y : Byte; a, b, c : Longint; begin c : = x * y + a * b;
Приведение типов var x, y : Byte; a, b, c : Longint; begin c : = Longint(x) * Longint(y) + a * b;
Пример : Пользовательский числовой тип со знаком Задачи: - сложение/вычитание - инициализация - ввод/вывод
Как делать? С “нуля” или воспользоваться существующими процедурами?
Сложение в позиционной системе счисления X = LX + Base * HX Y = Ly + Base * Hy Z = X + Y = = LX + Base * HX + Ly + Base * Hy = = (LX + Ly) + Base * (HX + Hy)
Вариант: type TLong = record L, H : Longint; end; { d = x + y + a + b } Sum(z, x, y); Sum(c, a, b); Sum(d, z, c);
Желательно: { d = x + y + a + b } d : = Sum(x, Sum(y, Sum(a, b))); Как осуществить?
Физическое совмещение переменных в памяти var y : Longint; x : array[0. . 3] of Byte;
Два способа представления строк: 1) Длина строки + массив символов (Char) 2) Массив символов + терминальный символ
program TLong; {ПОЛЬЗОВАТЕЛЬСКИЙ ЧИСЛОВОЙ ТИП СО ЗНАКОМ} const Base = 100000; Dcm = 9; Len = 8; type Long = String[Len]; Long 1 = record Ln : Byte; L, H : Longint; end;
function Long 2 Int(X : Long) : Longint; var X 1 : Long 1 absolute X; begin Long 2 Int : = X 1. L + (Base * X 1. H); end; function Int 2 Long(X : Longint) : Long; var Z 1 : Long 1; Z : Long absolute Z 1; begin Z 1. Ln : = Len; Z 1. L : = X mod Base; Z 1. H : = X div Base; Int 2 Long : = Z; end;
function Sum(X, Y : Long) : Long; var Z : Long; X 1 : Long 1 absolute X; Y 1 : Long 1 absolute Y; Z 1 : Long 1 absolute Z; begin Z 1. Ln : = Len; Z 1. H : = X 1. H + Y 1. H; Z 1. L : = X 1. L + Y 1. L; if Abs(Z 1. L) >= Base then if Z 1. L >= 0 then begin Dec(Z 1. L, Base); Inc(Z 1. H, 1); end else begin Inc(Z 1. L, Base); Dec(Z 1. H, 1); end;
if (Z 1. H > 0) and (Z 1. L < 0) then begin Inc(Z 1. L, Base); Dec(Z 1. H, 1); end else if (Z 1. H < 0) and (Z 1. L > 0) then begin Dec(Z 1. L, Base); Inc(Z 1. H, 1); end; Sum : = Z; end;
function Sgn(X : Long) : Longint; var X 1 : Long 1 absolute X; begin Sgn : = 1; if (X 1. L < 0) or (X 1. H < 0) then Sgn : = - 1 else if (X 1. L = 0) and (X 1. H = 0) then Sgn : = 0; end; function Inv(X : Long) : Long; var Z : Long; X 1 : Long 1 absolute X; Z 1 : Long 1 absolute Z; begin Z 1. Ln : = Len; Z 1. H : = - X 1. H; Z 1. L : = - X 1. L; Inv : = Z; end;
function Cmp(X, Y : Long) : Longint; begin Cmp : = Sgn(Sum(X, Inv(Y))); end; function Str 2 Long(S : String) : Long; var Z : Long; Z 1 : Long 1 absolute Z; Hs, Ls : String; Sign : Boolean; Code : Integer; begin Z 1. Ln : = Len; Z 1. H : = 0; Z 1. L : = 0; Sign : = False; if Length(S) > 0 then if S[1] = '-' then begin Sign : = True; Delete(S, 1, 1); end;
Hs : = ''; Ls : = ''; if Length(S) <= Dcm then Ls : = S else begin Ls : = Copy(S, Length(S) + 1 - Dcm, Dcm); Hs : = Copy(S, 1, Length(S) - Dcm); end; Val(Ls, Z 1. L, Code); Val(Hs, Z 1. H, Code); if Sign then Z : = Inv(Z); Str 2 Long : = Z; end;
function Long 2 Str(X : Long) : String; var X 1 : Long 1 absolute X; Ls, Hs : String; begin Str(Abs(X 1. L), Ls); while Length(Ls) < Dcm do Ls : = '0' + Ls; Str(Abs(X 1. H), Hs); Hs : = Hs + Ls; while (Length(Hs) > 1) and (Hs[1] = '0') do Delete(Hs, 1, 1); if Sgn(X) < 0 then Hs : = '-' + Hs; Long 2 Str : = Hs; end;
Побочное действие функции var X, Y : Boolean; function Do. It : Boolean; begin Y : = True; … end; … if X and Do. It then …
Внутреннее представление переменных var X, Y : Longint; function Factorial(N : Longint) : Longint; begin if N <= 1 then Factorial : = 1 else Factorial : = N * Factorial(N -1); end; procedure Do. It(A, B : Word; var Z : Longint); begin … end;
Динамические списки program Stroka; { ВАРИАНТ-А } const TStr. Size = 9; type PStr = ^TStr; TStr = record S : String[TStr. Size]; N : PStr; end;
function New. Str(S : String) : PStr; var P 1, P 2 : PStr; begin P 1 : = Nil; P 2 : = Nil; while S <> '' do begin if P 2 = Nil then begin New(P 2); P 1 : = P 2; end else begin New(P 2^. N); P 2 : = P 2^. N; end; P 2^. N : = Nil; P 2^. S : = Copy(S, 1, TStr. Size); Delete(S, 1, TStr. Size); end; New. Str : = P 1; end;
function Get. Str(P : PStr) : String; var S : String; begin S : = ''; while P <> Nil do begin S : = S + P^. S; P : = P^. N; end; Get. Str : = S; end;
procedure Del. Str(var P : PStr); var P 1 : PStr; begin P 1 : = P; while P 1 <> Nil do begin P 1 : = P 1^. N; Dispose(P); P : = P 1; end; procedure Put. Str(var P : PStr; S : String); begin Del. Str(P); P : = New. Str(S); end;
var P 1 : PStr; begin P 1 : = Nil; Put. Str(P 1, ‘Пример строки текста'); Write. Ln(Get. Str(P 1), '<'); Put. Str(P 1, ‘Другая строка'); Write. Ln(Get. Str(P 1), '<'); Put. Str(P 1, ''); Write. Ln(Get. Str(P 1), '<'); end.
program Stroka; { ВАРИАНТ-B } const TStr. Size = 9; type PStr = ^TStr; TStr = record S : String[TStr. Size]; N : PStr; end;
function Get. Str(P : PStr) : String; var S : String; begin S : = ''; while P <> Nil do begin S : = S + P^. S; P : = P^. N; end; Get. Str : = S; end;
procedure Put. Str(var P : PStr; S : String); var P 1, P 2 : PStr; Empty : Boolean; begin P 1 : = P; Empty : = (S = ''); if not Empty then if P 1 = Nil then begin New(P 1); P 1^. N : = Nil; P : = P 1; end; while S <> '' do begin P 1^. S : = Copy(S, 1, TStr. Size); Delete(S, 1, TStr. Size); if S <> '' then if P 1^. N <> Nil then P 1 : = P 1^. N else begin New(P 1^. N); P 1 : = P 1^. N; P 1^. N : = Nil; end;
P 2 : = P 1; if Empty then P : = Nil else if P 2 <> Nil then begin P 2 : = P 2^. N; P 1^. N : = Nil; P 1 : = P 2; end; while P 2 <> Nil do begin P 2 : = P 2^. N; Dispose(P 1); P 1 : = P 2; end;
function New. Str(S : String) : PStr; var P : PStr; begin P : = Nil; Put. Str(P, S); New. Str : = P; end; procedure Del. Str(var P : PStr); begin Put. Str(P, ''); end;
Кэш ( cache ) Алгоритмы вытеснения: LRU - Least Recently Used LFU - Least Frequently Used MRU - Most Recently Used ARC - Adaptive Replacement Cache Алгоритмы записи: WRITE-BACK – отложенная запись WRITE-THROUGH – сквозная запись
program LRU; { Least Recently Used } const cache_max = 128; type t_data = String; p_data = ^t_data; t_item = record tag : Longint; data : p_data; end; var cache : array[0. . cache_max - 1] of t_item; size : Longint; f : file of t_data;
procedure search(id : Longint; get : Boolean; var x : t_data); var i, k : Longint; found : Boolean; item : t_item; begin k : = 0; found : = False; while (k < size) and not found do if Abs(cache[k]. tag) = id then found : = True else Inc(k); if k = cache_max then begin k : = cache_max - 1; Dec(size); with cache[k] do if tag < 0 then begin Seek(f, Abs(tag)); Write(f, data^); end;
if not found then begin Inc(size); with cache[k] do begin tag : = id; if get then begin Seek(f, tag); Read(f, data^); end; item : = cache[k]; for i : = k downto 1 do cache[i] : = cache[i - 1]; cache[0] : = item; with cache[0] do if get then x : = data^ else begin data^ : = x; tag : = - Abs(tag); end;
var k : Longint; begin Assign(f, 'main. dat'); Reset(f); size : = 0; for k : = 0 to cache_max - 1 do with cache[k] do begin tag : = 0; New(data); end; {. . . }
{. . . } for k : = 0 to cache_max - 1 do with cache[k] do begin if tag < 0 then begin Seek(f, Abs(tag)); Write(f, data^); end; Dispose(data); end; Close(f); end.
program LFU; { Least Frequently Used } const cache_max = 128; freq_max = Max. Longint; type t_data = String; p_data = ^t_data; t_item = record tag, freq : Longint; data : p_data; end; var cache : array[- 1. . cache_max - 1] of t_item; size : Longint; f : file of t_data;
procedure search(id : Longint; get : Boolean; var x : t_data); var i, k : Longint; found : Boolean; item : t_item; begin k : = 0; found : = False; while (k < size) and not found do if Abs(cache[k]. tag) = id then found : = True else Inc(k); if k = cache_max then begin k : = cache_max - 1; Dec(size); with cache[k] do if tag < 0 then begin Seek(f, Abs(tag)); Write(f, data^); end;
if not found then begin Inc(size); with cache[k] do begin tag : = id; freq : = 0; if get then begin Seek(f, tag); Read(f, data^); end; Inc(cache[k]. freq);
item : = cache[k]; while item. freq > cache[k - 1]. freq do begin cache[k] : = cache[k - 1]; Dec(k); end; cache[k] : = item; if cache[0]. freq = freq_max then for i : = 0 to size - 1 do cache[i]. freq : = cache[i]. freq div 2; with cache[k] do if get then x : = data^ else begin data^ : = x; tag : = - Abs(tag); end;
var k : Longint; begin Assign(f, 'main. dat'); Reset(f); cache[- 1]. freq : = freq_max; size : = 0; for k : = 0 to cache_max - 1 do with cache[k] do begin tag : = 0; New(data); end; {. . . }
{. . . } for k : = 0 to cache_max - 1 do with cache[k] do begin if tag < 0 then begin Seek(f, Abs(tag)); Write(f, data^); end; Dispose(data); end; Close(f); end.
Инкрементирование указателей var x : array [min. . max] of t_data; {. . . } for k : = min to max – 1 do x[k] : = x[k + 1]; Адрес элемента массива x[k] : base + (k – min) * Size. Of(t_data);
var p 1, p 2 : ^t_data; {. . . } p 1 : = @x[min]; p 2 : = p 1; Inc(p 2); for k : = min to max – 1 do begin p 1^ : = p 2^; Inc(p 1); Inc(p 2); end;
Работа с битами AND – побитовое логическое умножение OR – побитовое логическое сложение NOT – побитовое логическое отрицание Операторы сдвига :
Пример : битовый массив const max_bit = 1024; type t_bits = array[0. . max_bit div 8 - 1] of Byte;
procedure put_bit(var bits : t_bits; bit : Longint; value : Boolean); begin if value then bits[bit div 8] : = bits[bit div 8] or (1 shl (bit mod 8)) else bits[bit div 8] : = bits[bit div 8] and not (1 shl (bit mod 8)); end; function get_bit(var bits : t_bits; bit : Longint) : Boolean; begin get_bit : = (bits[bit div 8] and (1 shl (bit mod 8))) <> 0; end;
Задачка из журнала «Квант» (раздел «Квант для младших школьников» ) В доме 64 квартиры. Дети играют во дворе в такую игру. Один из детей должен отгадать номер квартиры другого. Разрешается задавать только такие вопросы, на которые можно ответить либо «да» , либо «нет» . Вопрос: за какое минимальное число вопросов можно гарантированно отгадать номер квартиры?
Поиск в массиве (поиск делением пополам) program bin_seek; const length_a = 10000; type t_array = array[1. . length_a] of Longint; var a : t_array;
function bin_search(x : Longint; var a : t_array) : Longint; var L, R, m : Longint; begin L : = 1; R : = length_a + 1; while L < R do begin m : = (L + R) div 2; if a[m] < x then L : = m + 1 else R : = m; end; bin_search : = L; end;
Инвариант: 1) выполняется в начале алгоритма; 2) для каждого блока верно то, что если он выполняется перед его началом, то он выполняется и после него; 3) в конце алгоритма выполнение инварианта означает достижение цели алгоритма.
function bin_search(x : Longint; var a : t_array) : Longint; var L, R, m : Longint; begin L : = 1; R : = length_a + 1; while L < R do begin m : = (L + R) div 2; if a[m] < x then L : = m + 1 else R : = m; end; bin_search : = L; end; Инвариант:
alg-01.ppt