文章目录

Perl 数组操作:push() 与 pop()

发布于 2026-04-04 05:00:58 · 浏览 2 次 · 评论 0 条

Perl 数组操作:push() 与 pop()

Perl 中的数组是动态的、有序的元素集合。push()pop() 是两个最常用的数组操作函数,分别用于在数组末尾添加移除元素。它们的行为类似于栈(stack)结构中的“入栈”和“出栈”,使用起来非常直观。


push():向数组末尾添加元素

push() 函数的作用是把一个或多个元素追加到数组的末尾。

调用语法

push(@array, $element);
# 或一次添加多个
push(@array, $elem1, $elem2, $elem3);

执行效果

  • 原数组长度增加。
  • 新元素按顺序排在最后。
  • 函数返回操作后数组的总长度(但通常我们不关心这个返回值)。

操作步骤

  1. 准备一个数组变量,例如 @fruits = ("apple", "banana");
  2. 调用 push(),把新元素传入:
    push(@fruits, "cherry");
  3. 此时 @fruits 的内容变为 ("apple", "banana", "cherry")

你也可以一次添加多个元素:

push(@fruits, "date", "elderberry");

执行后,数组变成 ("apple", "banana", "cherry", "date", "elderberry")

注意:push() 的第一个参数必须是数组变量(以 @ 开头),不能是数组引用或列表字面量。


pop():从数组末尾移除元素

pop() 函数的作用是从数组末尾取出并移除最后一个元素。

调用语法

$last_element = pop(@array);
```

**执行效果**:
- 数组长度减 1。
- 被移除的元素作为函数的返回值。
- 如果数组为空,`pop()` 返回 `undef`(Perl 中的“未定义”值)。

### 操作步骤

1. **确保数组非空**(可选,但避免逻辑错误)。
2. **调用 `pop()`** 并接收返回值:
   ```perl
   my $removed = pop(@fruits);
  1. `$removed` 现在保存了被移除的元素,而 `@fruits` 少了一个末尾项。 例如,若 `@fruits = ("apple", "banana", "cherry")`,执行: ```perl my $fruit = pop(@fruits);
    
    之后:
  • `$fruit` 的值是 `"cherry"`, - `@fruits` 变为 `("apple", "banana")`。 如果连续调用 `pop()`: ```perl pop(@fruits); # 移除 "banana" pop(@fruits); # 移除 "apple" ``` 此时 `@fruits` 为空数组 `()`。 --- ## 组合使用:模拟栈操作 `push()` 和 `pop()` 天然支持“后进先出”(LIFO)的栈行为。你可以用它们轻松实现撤销操作、表达式求值、深度优先搜索等算法。 ### 示例:简易撤销历史 ```perl my @history = (); my $current = "start";

执行操作并记录历史

$current = "step1"; push(@history, $current);

$current = "step2"; push(@history, $current);

撤销:回到上一步

$current = pop(@history); # $current = "step1"


每次“执行”就 `push()`,每次“撤销”就 `pop()`,逻辑清晰且高效。

---

## 常见误区与注意事项

| 问题 | 正确做法 | 错误示例 |
| :--- | :---: | :--- |
| 对标量使用 `push` | 必须作用于数组变量 | `push($scalar, "x")` ❌ |
| 忘记接收 `pop()` 返回值 | 若需要被移除的值,应赋值给变量 | `pop(@arr);`(丢弃结果,有时合理,但需明确意图) |
| 在空数组上调用 `pop()` | 合法,但返回 `undef` | 需用 `defined()` 判断是否真有值 |

例如,安全地处理空数组:
```perl
if (@stack) {
    my $top = pop(@stack);
    # 处理 $top
}
```
或者:
```perl
my $item = pop(@stack);
if (defined $item) {
    # 使用 $item
}

性能说明

push()pop() 的时间复杂度都是 O(1) —— 无论数组多大,操作速度几乎不变。这是因为 Perl 内部为数组预留了额外空间,并维护了起始和结束指针,无需移动已有元素。

相比之下,对数组开头操作(如 shift() / unshift())可能涉及内存移动,效率较低。因此,优先使用 push() / pop() 而非 unshift() / shift(),除非逻辑上必须从头部操作。


实战练习:括号匹配检查

利用 push()pop() 可快速验证括号是否配对:

sub is_balanced {
    my ($str) = @_;
    my @stack = ();
    
    for my $char (split //, $str) {
        if ($char eq '(') {
            **push**(@stack, $char);
        } elsif ($char eq ')') {
            return 0 unless @stack;      # 多余右括号
            **pop**(@stack);              # 匹配成功,弹出左括号
        }
    }

    return @stack == 0;  # 栈空则匹配
}

# 测试
print is_balanced("((()))") ? "OK" : "NO";  # OK
print is_balanced("(()")    ? "OK" : "NO";  # NO

此代码逐字符扫描字符串,遇到左括号就 push(),遇到右括号就 pop()。若中途栈空却要 pop(),说明右括号多余;若结束时栈非空,说明左括号多余。


my @list = (1, 2, 3);
push(@list, 4);        # @list = (1,2,3,4)
my $last = pop(@list); # $last = 4, @list = (1,2,3)

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文