我被分配了一个任务,用给定的参数在 Perl 中创建一个循环链表,不使用数组或散列来存储数据,只使用引用。该结构中的第一个元素的值为 0,与用户的输入无关。它还应该支持使用“-”和“+”遍历当前选定的元素。程序的输出总是从预定义的元素开始,值为0。所以结果应该是这样的:
./task.pl 3 2 1
0 3 2 1
./task.pl A D - B C + E
0 A B C D E
./task.pl A - B
0 B A
我现在想出的代码是:
#!/usr/bin/perl
use strict;
use warnings;
my @elements = @ARGV;
my ($first, $last);
$first = { value => '0', 'prev' => $first, 'next' => $first };
my $pointer = \$first;
for (@elements) {
if ($_ == '-') {
} elsif ($_ == '+') {
} else {
$_ = $pointer->{'next'};
$_ = { value => "$_", 'prev' => $pointer, 'next' => undef};
$pointer = \$_;
$last = $_;
}
}
我不知道如何进一步进行此操作,也不能使用像 Class::Struct
这样的导入。
最佳答案
首先,您使用的是哈希。 {}
创建一个哈希并返回对其的引用。这是对的。哈希被用作结构/类,这不是赋值希望您避免的。
其次,您有 $first
和 $last
以及一个虚假的初始元素。所有这些都是错误的。您只需要我的 my $pointer;
,尽管我会称之为 my $current;
。
第三,使用对标量的引用 (\$var
)。这在这里没有用。对 {}
返回的哈希值的引用就足够了。
进入代码。共有三个不同的组件:插入第一个元素、+
和 -
、插入以及打印所构建的列表。
插入第一个元素
第一个参数很特殊。不能是 +
和 -
。其他插入总是在另一个元素之后插入,但第一个插入的情况并非如此。
简而言之,我们创建一个完全由值为第一个元素的节点组成的列表。
我们使用undef
来指示不存在的节点。
my $pointer = { value => shift(@elements), prev => undef, next => undef };
+
和 -
+
和 -
更改当前节点(如 $pointer
所示)。
如果接收到+
,则希望$pointer
指向当前节点的prev
字段所指向的节点。
如果收到-
,则希望$pointer
指向当前节点的prev
字段所指向的节点。
你总是要问自己是否有特殊情况,+
和 -
各有一个特殊情况。可能会尝试到达第一个节点之前的节点 (A - -
),也可能会尝试到达最后一个节点之后的节点 (A +
)。如果尝试到达不存在的节点,您应该死亡
。
插入
我们总是在当前节点(一个 $pointer
引用)之后插入。
我们再次询问自己是否存在特殊情况(例如在已经位于第一个节点时尝试使用 -
)。但没有。 $pointer
将始终指向有效节点。
在列表中插入节点后,我们想让 $pointer
引用新创建/插入的节点。
打印列表
我们想要从头到尾打印整个列表,因此我们需要首先找到列表的开头。这与重复应用 -
相同的操作,直到找到第一个节点。 (第一个节点是没有前一个节点的节点。)
然后,这只是一个以另一个方向遍历列表的问题(就像 +
那样),并在遍历过程中打印值。
关于algorithm - 如何在 Perl 中创建循环链表而不使用数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71496243/