实际上,TStack
它由动态数组提供支持。
如果你真的想要,你可以滥用这个事实让堆栈从底部删除项目,但现在你将与堆栈作斗争。
我认为使用循环列表是一个更好的主意。
一个简单的设计可能会像这样工作。
type
TCircularList<T> = class(TObject);
private
FStorage: TList<T>;
FCapacity: cardinal; //duplication for performance reasons
FCurrentIndex: cardinal;
protected
function GetItem(index: cardinal): T;
procedure SetItem(index: cardinal; const Value: T);
public
constructor Create(Size: cardinal = 10);
destructor Destroy; override;
procedure Add(const Item: T);
property Items[index: cardinal]: T read GetItem write SetItem; default;
end;
constructor TCircularList<T>.Create(Size: cardinal = 10);
begin
inherited Create;
Assert(Size >= 2);
FStorage:= TList<T>.Create;
FCapacity:= Size;
FStorage.Capacity:= Size;
end;
destructor TCircularList<T>.Destroy;
begin
FStorage.Free;
inherited;
end;
procedure TCircularList<T>.Add(const Item: T);
begin
FCurrentIndex:= (FCurrentIndex + 1) mod FCapacity;
FStorage[FCurrentIndex]:= Item;
end;
function TCircularList<T>.GetItem(index: cardinal): T;
var
cIndex: cardinal;
begin
cIndex:= Index mod FCapacity;
Result:= FStorage[index];
end;
procedure TCircularList<T>.SetItem(index: cardinal; const Value: T);
var
cIndex: cardinal;
begin
cIndex:= index mod FCapacity;
FStorage[index]:= Value;
end;
显然你需要更多的方法,比如 last 和 delete 方法,但我把它留给你,你应该可以从这里推断出来。
可用性评论
我不得不说,从用户体验的角度来看,我认为撤消/重做功能的想法很糟糕。
为什么没有快照列表,您可以及时前后移动,就像您在磁盘上保存许多备份文件的情况一样。
撤消功能要求您准确记住您在最后 x 步骤中所做的事情,这些步骤不能很好地扩展。
我也不明白为什么必须有限制,为什么不允许内存/磁盘空间允许的尽可能多的撤消/快照?