Perl 数据结构学习笔记

Perl 脚本常用数据结构的学习总结用于以后自己参考,包括数组、散列、散列的数组、数组的散列、混合结构的使用,参考资料:Perl数据结构,Perl 教程

数组,二维数组(数组的数组)

一个数组的创建和索引

my @a = ("abc", "abc", "abc") ;
my $size = @a; # 数组大小
my $tmp = $a[0]; # 数组索引
my @queue;
push @queue, \@a; # 二维数组
print " $queue[0][0]"; # 二维数组索引

需要注意的是,二维数组其实就是一个放置每个一维数组引用(指针)的一维数组,所以在给二维数组添加元素的时候,push的是一个一维数组的引用

push @queue, \@a; # 二维数组

那么索引这个二维数组的写法也就好理解了,引用 “ \ ” 这个概念先mark下,方便后续理解更复杂的数据结构,对于不用类型的数据结构可以用 $, @, %来解引用。

print " $queue[0][0]"; # 二维数组索引

类似的,多维数组的创建和索引也就好理解了

my @queue3;
push @queue3, \@queue;
print "$queue3[0][0][0]\n";

请记住在每一对相邻的花括弧或方括弧之间有隐含的 ->,因此下面三行是等价的。

$AoA[2][3]
$ref_to_AoA->[2][3]
$ref_to_AoA->[2]->[3]

{ } 或 [ ] 之间的 -> 是可省略的。但下面这种情况要注意,虽然之前我们使用 $queue[0][0] 的写法省略了->,但是我们需要清楚 $_内存放的仍是一个一维数组的引用,解析时不能忽略 ->。

for(@queue){print "$_->[0]\n";
}

数组作为传参

Perl 支持函数之间的传参是一个标量,或者是一个数组。当然这个数组可以是二维数组,包含多个数组的引用,那就可以传更多参数了。

my @getPara;
my @givePara = ("aa","bb","cc");
@getPara = testSub(@givePara);
print "my getPara[0]: $getPara[0]";
sub testSub{my @input = @_;print "my input[0]: $input[0]\n";my @output = ("11", "22", "33");return @output;
}

下面是利用多维数组传递多组传参的例子,这里我们将 @givePara1, @givePara2 的引用放在 @givePara 中作为传参给子函数。

$input[0] 存放的是 @givePara1 的引用,因此需要通过解引用将参数传递给@input1
$input2是另一种方法,继承 @givePara2 的引用,在索引的时候通过 ->来解引用

my @getPara;
my @givePara1 = ("aa","bb","cc");
my @givePara2 = ("dd","ee","ff");
my @givePara = (\@givePara1,\@givePara2);
@getPara = testSub(@givePara);
@getPara1 = @{$getPara[0]};
@getPara2 = @{$getPara[1]};
print "my getPara[0][0]: $getPara[0][0]\n";
print "my getPara1[0]: $getPara1[0]\n";
print "my getPara2[0]: $getPara2[0]\n";
sub testSub{my @input = @_;my @input1,$input2;@input1 = @{$input[0]};$input2 = $input[1];print "my input[1][0]: $input[1][0]\n";print "my input1[0]: $input1[0]\n";print "my input2[0]: $input2->[0]\n";my @output1 = ("11", "22", "33");my @output2 = ("44", "55", "66");my @output = (\@output1,\@output2);return @output;
}

散列,也叫哈希

哈希的创建和索引

哈希是很多条记录键字(key)与值(val)一一对应组合的集合,一个哈希的创建和索引是这样的:

my $a = 18, $b = 180, $c = 150;
$str = "xiaoming";
my %student = ("name" => $str, # key => val,键字的 " " 也可以忽略"age" => $a,"high" => $b,"weight" => $c
);
print "$student{'name'}\n";

新增记录,可以直接加,索引键字的 “” ''也是可以忽略的
PS:hash里面的记录是乱序的哦

my $scr = 99;
$student{score} = $scr;
print "$student{score}\n";

哈希作为传参

函数之间传递哈希的时候,Perl是将它放到数组 @_ 里面传递的,下面程序可以看出来:

my $a = 18, $b = 180, $c = 150;
$str = "xiaoming";
my %student = (name => $str,"age" => $a,"high" => $b,"weight" => $c
);
testSub();
sub testSub{my @input = @_;for (@input) {print "$_\n";}
}

它的打印结果是这样的:(哈希是乱序的)

high
180
name
xiaoming
age
18
weight
150

不过也是可以直接将结果赋值到哈希中的

my $a = 18, $b = 180, $c = 150;
$str = "xiaoming";
my %student = (name => $str,"age" => $a,"high" => $b,"weight" => $c
);
my %getStu = testSub(%student);
foreach my $key (keys %getStu) {my $val = $getStu{$key};print "$key : $val\n";
}
sub testSub{my %inputHash = @_;foreach my $key (keys %inputHash) {my $val = $inputHash{$key};print "$key : $val\n";}print "----------------\n";my $aa = 19, $bb = 181, $cc = 151;$strr = "xiaoming";my %student = (name => $strr,"age" => $aa,"high" => $bb,"weight" => $cc);return %student;
}

当然,也可以传递哈希的引用,再通过 % 解引用。

my $a = 18, $b = 180, $c = 150;
$str = "xiaoming";
my %student = (name => $str,"age" => $a,"high" => $b,"weight" => $c
);my $getStuTmp = testSub(%student); #### <----------
my %getStu = %{$getStuTmp};        #### <----------
foreach my $key (keys %getStu) {my $val = $getStu{$key};print "$key : $val\n";
}sub testSub{my %inputHash = @_;foreach my $key (keys %inputHash) {my $val = $inputHash{$key};print "$key : $val\n";}print "----------------\n";my $aa = 19, $bb = 181, $cc = 151;$strr = "xiaoming";my %student = (name => $strr,"age" => $aa,"high" => $bb,"weight" => $cc);return \%student;              #### <----------
}

这里有点麻烦,但是要传递多个哈希表就有思路了,搞一个哈希的数组就可以了。

哈希的数组

一个哈希数组的创建和索引

my $a = 18, $b = 180, $c = 150;
$str = "xiaoming";
my %student = ( name => $str,age => $a,high => $b,weight => $c );
my @class = ({ name => $str,age => $a,high => $b,weight => $c },{ name => $str,age => $a,high => $b,weight => $c }
);
for my $x (0..5){$str = $str.$x; $a = $a + 1; $b = $b + 1; $c = $c + 1;my %tmpStu = ( name => $str,age => $a,high => $b,weight => $c );push @class,\%tmpStu;
}
print " ---> $class[3]{name}\n";

哈希数组作为传参

与数组作为传参的使用类似,注意索引,其他不再赘述。

数组的哈希

创建一个数组的哈希以及索引数组元素

一个数组的哈希,键字对应的值是数组的引用,在添加数组哈希或者索引数组元素的时候注意引用与解引用的区分

my %class = (person => ["xiaoming","xiaogang","xiaohua"],age    => ["11","12","13"],high   => ["120","130","140","150"]
);
my @a = ("60","70","80","90");
$class{weight} = \@a;
print "$class{age}->[2]\n";

数组的哈希作为传参

与哈希作为传参的使用类似,注意索引,其他不再赘述。

哈希的哈希

与数组的哈希类似,键字对应的值是的哈希引用,注意引用

my %student1 = ( person => "xiaoming", age => "11", high => "120" );
my %student2 = ( person => "xiaogang", age => "12", high => "130" );
my %student3 = ( person => "xiaohua" , age => "13", high => "140" );
my %class = (monitor => \%student1,commissary1 => \%student2
);
$class{commissary2} = \%student3;
print "$class{monitor}->{person}\n";

函数的哈希

9.5 函数的散列
在使用 Perl 书写一个复杂的应用或者网络服务的时候,你可能需要给你的用户制作一大堆命令供他们使用。这样的程序可能有象下面这样的代码来检查用户的选择,然后采取相应的动作:

if    ($cmd =~ /^exit$/i)     { exit }
elsif ($cmd =~ /^help$/i)     { show_help() }
elsif ($cmd =~ /^watch$/i)    { $watch = 1 }
elsif ($cmd =~ /^mail$/i)     { mail_msg($msg) }
elsif ($cmd =~ /^edit$/i)     { $edited++; editmsg($msg); }
elsif ($cmd =~ /^delete$/i)   { confirm_kill() }
else {warn "Unknown command: `$cmd'; Try `help' next time\n";
}

你还可以在你的数据结构里保存指向函数的引用,就象你可以存储指向数组或者散列的引用一样:

%HoF = (                           # Compose a hash of functionsexit    =>  sub { exit },help    =>  \&show_help,watch   =>  sub { $watch = 1 },mail    =>  sub { mail_msg($msg) },edit    =>  sub { $edited++; editmsg($msg); },delete  =>  \&confirm_kill,
);if   ($HoF{lc $cmd}) { $HoF{lc $cmd}->() }   # Call function
else { warn "Unknown command: `$cmd'; Try `help' next time\n" }

在倒数第二行里,我们检查了声明的命令名字(小写)是否在我们的“遣送表”%HoF 里存在。如果是,我们调用响应的命令,方法是把散列值当作一个函数进行解引用并且给该函数传递一个空的参数列表。我们也可以用
&{ $HoF{lc $cmd} }( ) 对散列值进行解引用,或者,在 Perl 5.6 里,可以简单地是 $HoF{lc $cmd}
()。

混合数据结构的使用

Perl 程序中还有可能用到数组、哈希等数据结构的混合数据结构,这种也可以将其合并为一个混合结构

my $testStr = "I am a string";
my @test = ("aa","bb","cc");
my $a = 18, $b = 180, $c = 150;
my $str = "xiaoming";
my %student = ( name => $str,age => $a,high => $b,weight => $c );
my @class = ({ name => $str."_1",age => $a,high => $b,weight => $c},{ name => $str."_2",age => $a,high => $b,weight => $c}
);
my %school = (person => ["xiaoming_3","xiaogang","xiaohua"],age    => ["11","12","13"],high   => ["120","130","140","150"]
);
my $rec = {STR => $testStr,QUE => \@test,HASH => \%student,HASHQUE => \@class,QUEHASH => \%school
};
$rec->{STRADD} = $str;
print "string  try : $rec->{STR} \n";
print "queue   try : $rec->{QUE}->[0]\n";
print "hash    try : $rec->{HASH}->{name}\n";
print "hashque try : $rec->{HASHQUE}->[0]{name}\n";
print "quehash try : $rec->{QUEHASH}->{person}[0]\n";
print "stringadd  try : $rec->{STRADD} \n";

注意混合结构 $rec 定义取值使用的是 { } ,它是整个混合结构的引用,所以可以看到后边索引内部元素的时候都要先用 -> 解引用(划重点)

好了,以上就是这次全部的学习内容了,函数哈希没实际用到,有遇到的话下次补充~

Perl 数据结构学习笔记相关推荐

  1. 数据结构学习笔记(七):哈希表(Hash Table)

    目录 1 哈希表的含义与结构特点 1.1 哈希(Hash)即无序 1.2 从数组看哈希表的结构特点 2 哈希函数(Hash Function)与哈希冲突(Hash Collision) 2.1 哈希函 ...

  2. 数据结构学习笔记(六):二叉树(Binary Tree)

    目录 1 背景知识:树(Tree) 2 何为二叉树(Binray Tree) 2.1 二叉树的概念与结构 2.2 满二叉树与完全二叉树 2.3 二叉树的三种遍历方式 3 二叉树及其遍历的简单实现(Ja ...

  3. 数据结构学习笔记(五):重识字符串(String)

    目录 1 字符串与数组的关系 1.1 字符串与数组的联系 1.2 字符串与数组的区别 2 实现字符串的链式存储(Java) 3 子串查找的简单实现 1 字符串与数组的关系 1.1 字符串与数组的联系 ...

  4. 数据结构学习笔记(四):重识数组(Array)

    目录 1 数组通过索引访问元素的原理 1.1 内存空间的连续性 1.2 数据类型的同一性 2 数组与链表增删查操作特性的对比 2.1 数组与链表的共性与差异 2.2 数组与链表增删查特性差异的原理 3 ...

  5. 数据结构学习笔记——顺序表的基本操作(超详细最终版+++)建议反复看看ヾ(≧▽≦*)o

    目录 前言 一.顺序表的定义 二.顺序表的初始化 三.顺序表的建立 四.顺序表的输出 五.顺序表的逆序输出 六.顺序表的插入操作 七.顺序表的删除操作 八.顺序表的按位和按值查找 基本操作的完整代码 ...

  6. Python数据结构学习笔记——链表:无序链表和有序链表

    目录 一.链表 二.无序链表 实现步骤分析 三.无序链表的Python实现代码 四.有序链表 实现步骤分析 五.有序链表的Python实现代码 结语 一.链表 链表中每一个元素都由为两部分构成:一是该 ...

  7. Python数据结构学习笔记——队列和双端队列

    目录 一.队列的定义 二.队列 实现步骤分析 三.队列的Python实现代码 四.队列的应用 六人传土豆游戏 五.双端队列的定义 六.双端队列 实现步骤分析 七.双端队列的Python实现代码 八.双 ...

  8. Python数据结构学习笔记——栈

    目录 一.栈的定义和特性 (一)栈的定义 (二)栈的反转特性 二.实现分析步骤 三.栈的Python实现代码 四.栈的应用 (一)匹配圆括号 (二)匹配符号 (三)模2除法(十进制转二进制) (四)进 ...

  9. 数据结构学习笔记:利用栈实现进制转换

    数据结构学习笔记:利用栈实现进制转换 一.除基倒取余法示意图 二.编写十进制转换成二进制Python程序 1.源代码 2.运行结果 其实Python提供了一

最新文章

  1. MFC中滚动条slider和编辑框edit的联动
  2. linux 433发送驱动
  3. 看图识物_看图识物:下面图里是什么植物呢?请朋友们评论区留言
  4. PS3支持的显示标准介绍
  5. vscode 中 markdown 插件和使用
  6. 你会想待下去吗?世界上25个最惊险的屋顶
  7. 在线JSON格式化工具
  8. 地理必修一三大类岩石_90后地理老师4天收700封情书!这波操作,绝了……
  9. php敏感代码屏蔽,PHP敏感词汇屏蔽或替换
  10. DataStreamer Exception
  11. Todd's Matlab讲义第5讲:二分法和找根
  12. 轻量级微信动态活码生成管理源码
  13. 7-5 3824经典游戏分数 20 作者 李佳单位 重庆大学
  14. 以本职工作为挡箭牌推托,久而久之,你就只能原地踏步。
  15. SDNU-1093.DNA排序
  16. python爬取小说章节_python之如何爬取一篇小说的第一章内容
  17. python中箭头是什么意思_python流程框里面的箭头是什么意思
  18. 计算机学域名,计算机域名是什么?有什么用?怎么能知道计算机的域名?
  19. 关于iPhone的一个广告加载问题
  20. 【UE4】材质编辑器教程笔记整理

热门文章

  1. PHP 字符串长度截取 之 解决微信消息字数限制
  2. 读书笔记也是遵循二八法则的
  3. 如何令电子邀请函设计变得与众不同?
  4. H5 监听手机浏览器 后台唤醒 激活
  5. 我的世界服务器如何修改武器,我的世界:自定义装备属性,让你自己动手来“调节”装备属性!...
  6. C Primer Plus笔记
  7. 迅视资管 全域零售时代 日化行业用精准服务应对新挑战
  8. 2022浙江省计算机三级网络及安全技术考试知识点总结
  9. 【AI绘图】咒术师的评级指南
  10. Spring:Failed to instantiate [XXX]: No default constructor found;的解决办法