unit FixedStack;
{$mode objfpc}{$H+}
{$codepage UTF-8}
interface
uses
{$ifdef unix}cwstring,{$endif}
SysUtils;
type
{ --- Шаг 1. Классы исключений --- }
// Базовый класс для всех ошибок стека
EStackError = class(Exception);
// Исключение при опустошении стека
EStackUnderflowError = class(EStackError);
// Исключение при переполнении стека (с дополнительным свойством)
EStackOverflowError = class(EStackError)
private
FCapacity: Integer; // Внутреннее поле для хранения емкости
public
constructor Create(ACapacity: Integer);
property Capacity: Integer read FCapacity; // Свойство для доступа извне
end;
{ --- Шаг 2. Класс фиксированного стека --- }
TFixedStack = class
private
FData: array of Integer; // Динамический массив, размер которого зафиксируем
FTop: Integer; // Индекс верхнего элемента (если -1, то стек пуст)
FCapacity: Integer; // Максимальная емкость стека
function GetCount: Integer;
function GetIsEmpty: Boolean;
function GetIsFull: Boolean;
public
constructor Create(ACapacity: Integer);
destructor Destroy; override;
procedure Push(AValue: Integer);
function Pop: Integer;
function Peek: Integer;
property Count: Integer read GetCount;
property Capacity: Integer read FCapacity;
property IsEmpty: Boolean read GetIsEmpty;
property IsFull: Boolean read GetIsFull;
end;
implementation
{ EStackOverflowError }
constructor EStackOverflowError.Create(ACapacity: Integer);
begin
// Вызываем конструктор предка и передаем туда отформатированное сообщение
inherited Create(Format('стек заполнен (ёмкость: %d)', [ACapacity]));
FCapacity := ACapacity;
end;
{ TFixedStack }
constructor TFixedStack.Create(ACapacity: Integer);
begin
if ACapacity <= 0 then
raise EStackError.Create('Емкость стека должна быть больше нуля');
FCapacity := ACapacity;
SetLength(FData, FCapacity); // Выделяем память под массив
FTop := -1; // Стек изначально пуст
end;
destructor TFixedStack.Destroy;
begin
SetLength(FData, 0); // Освобождаем массив
inherited Destroy;
end;
procedure TFixedStack.Push(AValue: Integer);
begin
if IsFull then
raise EStackOverflowError.Create(FCapacity);
Inc(FTop); // Двигаем указатель вершины вверх
FData[FTop] := AValue; // Записываем значение
end;
function TFixedStack.Pop: Integer;
begin
if IsEmpty then
raise EStackUnderflowError.Create('стек пуст');
Result := FData[FTop]; // Забираем значение с вершины
Dec(FTop); // Двигаем указатель вершины вниз
end;
function TFixedStack.Peek: Integer;
begin
if IsEmpty then
raise EStackUnderflowError.Create('стек пуст');
Result := FData[FTop]; // Просто возвращаем значение, не двигая указатель
end;
{ Геттеры свойств }
function TFixedStack.GetCount: Integer;
begin
Result := FTop + 1;
end;
function TFixedStack.GetIsEmpty: Boolean;
begin
Result := (FTop = -1);
end;
function TFixedStack.GetIsFull: Boolean;
begin
Result := (GetCount = FCapacity);
end;
end.