如何在不使用数组的情况下在 Perl 中创建循环链表?
How to create a circular linked list in Perl without using arrays?
我被分配了一项任务,要在 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
这样的导入。
首先,您使用的是哈希。 {}
创建一个散列和 returns 对它的引用。这是对的。哈希被用作 struct/class,这不是作业希望您避免的。
其次,您有 $first
和 $last
以及一个伪造的初始元素。所有这些都是错误的。你只需要我的 my $pointer;
,尽管我会称之为 my $current;
.
第三,您使用对标量的引用 ($var
)。这在这里没有用。对 {}
返回的散列的引用就足够了。
关于代码。共有三个不同的组件:插入第一个元素,+
和 -
,插入,以及打印构建的列表。
插入第一个元素
第一个参数比较特殊。不能是 +
和 -
。其他插入总是在另一个元素之后插入,但第一次插入不是这样。
简而言之,我们创建一个列表,该列表完全由一个值为第一个元素的节点组成。
我们用undef
表示一个non-existent节点。
my $pointer = { value => shift(@elements), prev => undef, next => undef };
+
和 -
+
和 -
更改当前节点(如 $pointer
所示)。
如果收到+
,则要$pointer
指向当前节点的prev
字段指向的节点。
如果收到-
,则要$pointer
指向当前节点的prev
字段指向的节点。
你总是要问自己是否有特殊情况,+
和-
各有一个。可能会尝试到达第一个节点之前的节点 (A - -
),也可能会尝试到达最后一个节点之后的节点 (A +
)。如果尝试到达 non-existent 节点,您应该 die
。
插入
我们总是在当前节点($pointer
引用)之后插入。
我们再次问自己是否有特殊情况(比如在第一个节点上尝试使用 -
)。但是有none。 $pointer
将始终指向有效节点。
在列表中插入一个节点后,我们想让 $pointer
引用新的 created/inserted 节点。
正在打印列表
我们想要从头到尾打印整个列表,所以我们需要从找到列表的开头开始。这与 -
重复应用相同的操作,直到找到第一个节点。 (第一个节点是没有前一个节点的节点。)
然后,这只是一个从另一个方向遍历列表的问题(就像 +
那样),边走边打印值。
我被分配了一项任务,要在 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
这样的导入。
首先,您使用的是哈希。 {}
创建一个散列和 returns 对它的引用。这是对的。哈希被用作 struct/class,这不是作业希望您避免的。
其次,您有 $first
和 $last
以及一个伪造的初始元素。所有这些都是错误的。你只需要我的 my $pointer;
,尽管我会称之为 my $current;
.
第三,您使用对标量的引用 ($var
)。这在这里没有用。对 {}
返回的散列的引用就足够了。
关于代码。共有三个不同的组件:插入第一个元素,+
和 -
,插入,以及打印构建的列表。
插入第一个元素
第一个参数比较特殊。不能是 +
和 -
。其他插入总是在另一个元素之后插入,但第一次插入不是这样。
简而言之,我们创建一个列表,该列表完全由一个值为第一个元素的节点组成。
我们用undef
表示一个non-existent节点。
my $pointer = { value => shift(@elements), prev => undef, next => undef };
+
和 -
+
和 -
更改当前节点(如 $pointer
所示)。
如果收到+
,则要$pointer
指向当前节点的prev
字段指向的节点。
如果收到-
,则要$pointer
指向当前节点的prev
字段指向的节点。
你总是要问自己是否有特殊情况,+
和-
各有一个。可能会尝试到达第一个节点之前的节点 (A - -
),也可能会尝试到达最后一个节点之后的节点 (A +
)。如果尝试到达 non-existent 节点,您应该 die
。
插入
我们总是在当前节点($pointer
引用)之后插入。
我们再次问自己是否有特殊情况(比如在第一个节点上尝试使用 -
)。但是有none。 $pointer
将始终指向有效节点。
在列表中插入一个节点后,我们想让 $pointer
引用新的 created/inserted 节点。
正在打印列表
我们想要从头到尾打印整个列表,所以我们需要从找到列表的开头开始。这与 -
重复应用相同的操作,直到找到第一个节点。 (第一个节点是没有前一个节点的节点。)
然后,这只是一个从另一个方向遍历列表的问题(就像 +
那样),边走边打印值。