delphi - 如何使用尚未初始化的变量
问题描述
我正在尝试创建一个具有字符串和节点数组的节点,但尚未创建其他节点,那么我该如何使用它们?稍后我将需要在“针对节点中的所有边”循环中访问特定节点的边。它是一种图形数据结构。该图是有向的,意味着节点 A 可以与 B 有连接,而 B 与 A 没有连接。
type
TNode = record
name: String;
edges: TNodeArray;
procedure Init(const aName: String; const aEdges: TNodeArray);
end;
TNodeArray = array of TNode;
procedure TNode.Init(const aName: String; const aEdges: TNodeArray);
begin
name := aName; edges := aEdges;
end;
function NewNode(const aName: String; const aEdges: TNodeArray): TNode;
begin
Result.Init(aName, aEdges);
end;
procedure Main;
var
n0, n1, n2, n3: TNode;
begin
n0 := NewNode('new york', TNodeArray.Create(n1, n2));
n1 := NewNode('london', TNodeArray.Create(n2));
n2 := NewNode('moscu', TNodeArray.Create(n1, n3));
n3 := NewNode('other city', nil); // 'other city' has no connections
end;
解决方案
在评论中,原来这是一个有向图。如果是这样,你可以使用这样的东西:
type
TNode = class
strict private
FName: string;
FOutgoingArcs: TList<TNode>;
function GetOutgoingArc(Index: Integer): TNode;
function GetOutgoingArcCount: Integer;
public
constructor Create(const AName: string);
procedure AddOutgoingArc(ANode: TNode);
procedure AddOutgoingArcs(const ANodes: array of TNode);
property OutgoingArcs[Index: Integer]: TNode read GetOutgoingArc;
property OutgoingArcCount: Integer read GetOutgoingArcCount;
property Name: string read FName write FName;
destructor Destroy; override;
end;
implementation
{ TNode }
procedure TNode.AddOutgoingArc(ANode: TNode);
begin
FOutgoingArcs.Add(ANode)
end;
procedure TNode.AddOutgoingArcs(const ANodes: array of TNode);
var
Node: TNode;
begin
for Node in ANodes do
AddOutgoingArc(Node);
end;
constructor TNode.Create(const AName: string);
begin
FName := AName;
FOutgoingArcs := TList<TNode>.Create;
end;
destructor TNode.Destroy;
begin
FOutgoingArcs.Free;
inherited;
end;
function TNode.GetOutgoingArcCount: Integer;
begin
Result := FOutgoingArcs.Count;
end;
function TNode.GetOutgoingArc(Index: Integer): TNode;
begin
Result := FOutgoingArcs[Index];
end;
我也认为跟踪单个列表中的所有节点很好,所以我会这样做
var
Nodes: TObjectList<TNode>;
function CreateNode(const AName: string): TNode;
begin
Result := TNode.Create(AName);
Nodes.Add(Result);
end;
现在我们可以玩了(确保先创建Nodes
:)Nodes := TObjectList<TNode>.Create(True{say})
:
var
NewYork,
London,
Paris,
Moscow: TNode;
begin
NewYork := CreateNode('New York');
London := CreateNode('London');
Paris := CreateNode('Paris');
Moscow := CreateNode('Moscow');
NewYork.AddOutgoingArc(London);
London.AddOutgoingArcs([NewYork, Paris, Moscow]);
Paris.AddOutgoingArcs([London, Moscow]);
Moscow.AddOutgoingArc(NewYork);
但是当然有一千种方法来设计这个。这只是一种可能的解决方案。
更新:
请注意,只有一个名为“London”的对象,因此如果您将其更改为“via Paris”,则会看到“via New York”:
Paris.OutgoingArcs[0].Name := 'The Capital of the United Kingdom';
现在
NewYork.OutgoingArcs[0].Name
也是'The Capital of the United Kingdom'
。
还要注意,与
Nodes := TObjectList<TNode>.Create(True)
节点将由Nodes
对象列表拥有(这就是True
意思),因此它们将在被释放时Nodes
被释放。因此,例如,如果您在自己的 class 中使用这些节点TTravelPlanner
,您可能想要 create Nodes
inTTravelPlanner.Create
和 do Nodes.Free
in TTravelPlanner.Destroy
。
推荐阅读
- google-cloud-platform - 如何配置 OBD2 跟踪器以发送和存储消息,例如 Google/Azure/WAS IoT
- metaprogramming - MT5/MQL5 如何用不同的货币进行 6 次交易
- replace - 在单个 Power BI Step/M 语句中更改字段类型和多个精确值替换
- python - 使用 Python 来“参与”Windows 的音频通道,类似于游戏或 youtube 视频,以避免在 7.1、5.1 等之间的不稳定切换
- c++ - 为什么我不应该将接口和实现放在一个文件中?
- django - 根据过滤的查询集有条件地在 Django admin 中显示列
- angular - 如何修复显示内存不足异常的 Ionic cordova 文档扫描仪
- ios - 我可以实时获取卡路里和步数以从 Watch 应用程序更新我的应用程序吗?
- amazon-cloudwatch - Cloudwatch 警报未将丢失数据视为未违反
- database - BigTable 聚合数据