Perl零零八速成系列---数据结构入门

生信者言 2018-07-03 09:33:11

阅读用时:全文共4小节,约4200字,约8

关键词:Perl语言、数据结构、变量操作



当你面对一堆数据心急如焚却无从下手的时候,是否希望立马出现一个编程牛人并以迅雷不及掩耳之势获取你想要的结果?


可是往往牛人很忙,远水救不了近火。



这时候是否恨不得自己瞬间变身为一名牛人?如果答案是肯定的,那么祝贺你,当你看到这篇文章时,就已经在变身牛人的路上了!

 

《Perl零零八速成系列》(共8节课)主要是面向无Perl编程经验或者Perl语言初学者,介绍Perl的基本知识和实用编程技巧。晨光与你一路,轻松点亮编程技能,一跃成为特工级的Perl编程牛人!

【本节内容】

本文内容包括Perl 语言的基本介绍、基本数据结构以及变量常用的操作。

 

1

什么是Perl语言


Perl (Practical Extractionand Report Language,可直译为 "实用报表提取语言" ) 是一种功能丰富的计算机程序语言,最初的设计者为拉里·沃尔(Larry Wall),于1987年12月18日发表。当前最新版本为Perl 6,于2015年12月25日更新。

 

Perl借取了C、sed、awk、shell 脚本语言以及很多其他程序语言的特性,因此Perl像C一样强大,像awk、sed等脚本描述语言一样方便。同时,由于Perl语言的高度灵活性,Perl被称为脚本语言中的瑞士军刀和万能胶水


此时笔者对Larry Wall的仰慕之情已如滔滔江水,连绵不绝,故奉上大神的皂片一张,供学习之余朝拜之

Larry Wall

 

有学过其它编程语言(如C语言)的同学一定记得(记忆加载中…),入门第一个编程代码便是"Hello World!"。


下面我们来看看,如何用 Perl 输出"Hello World!":

 

#!/usr/bin/perl  

print "Hello World!\n";

 

说明:

第1行:声明perl编译器的路径(一般情况下是/usr/bin/perl,依不同平台而异),通常表示方式为#!+ 解释器路径  (注意:不要将#!与Perl代码的注释符号#相混淆)。


第2行:使用print 函数输出字符串"Hello World!\n"; 其中" \n"表示换行符。

 

Perl程序一般以".pl"为脚本文件后缀,如hello.pl,将上述代码以文本形式保存到hello.pl,然后在Linux终端运行命令:

 

perl hello.pl

 

运行结果:Hello World!

 

PS: 以上为脚本运行方式,也可以直接在Linux终端中使用 -e 选项输入语句以直接在命令行执行代码(后面为了方便大家进行练习,所举例子以这种方式为主,大家有兴趣也可以改写成脚本形式后运行):

 

perl -e ' print "Hello World\n" '      #输出:Hello World

 


2

基本数据结构

 

变量是存储在内存中的数据,创建一个变量即会在内存上开辟一个空间。Perl变量不需要显式声明类型,一般使用等号(=)来赋值。普通的变量名可以包含字母(a-z,A-Z)、数字(0-9)或类型标识符后面的一个下划线字符(_),变量名对大小写敏感,而且第一个字符不能是数字


Perl变量有三种基本数据结构:标量、数组、哈希。下面,我们分别看下这三种数据结构:

 

 标量 

标量 ( scalar ) 是Perl语言中最简单的一种数据结构。这种数据结构的变量可以是数字,字符串,浮点数。在使用时在变量的名字前加上一个美元符号"$",也称为魔符 ( sigil ) ,表示是标量。例如:

$a=123;             #数字123

$b="Hello";        #字符串"Hello"

$c=3.14;            #浮点数3.14

 

小试牛刀:

perl -e ' $a=123;print "$a\n" '  

#输出:123

 

 数组 

列表 ( list ) 指的是标量的有序集合,而数组 ( array ) 则是储存列表的变量。数组变量以字符"@"开头,索引从0开始,例如:

@a=(1,2,3,4)                                    #数组a包含4个数字

@b=("Bob","Tom","Fred")               #数组b包含3个字符串

$a[0] 表示数组a的第一个元素,值为1;

$b[1] 表示数组b的第二个元素,值为"Tom";

$b[2] (或$b[-1] ) 表示数组b的第三个(或倒数第一个)元素,值为"Fred";

 

小试牛刀:

perl -e ' @b=("Bob","Tom","Fred");print"$b[-1] \n" '  

#输出:Fred

 

哈希 

哈希 ( hash ) 是一个无序的 key/value ( 键/值 ) 对集合。可以使用键作为下标获取值。哈希变量以字符"%"开头。例如:

%h=('a'=>1,'b'=>2);            #哈希%h包含2对键/值;

$h{'a'} 表示键'a'对应的值,大小为1;

 

小试牛刀:

perl -e ' %h=('a'=>1,'b'=>2);print "$h{'a'} \n" '  

#输出:1

 

PS: 需要注意的是,有几个系统保留的变量名因为有其特殊的用途,不能被用来命名普通的变量,比如$1、$2、$3、…、$_、$#、@_、$!、$/等等,这些特殊变量在后面的课程会逐一给大家介绍。

 

3

标量运算基本操作

 

Perl变量作为数据的存储结构单元,可以进行各种处理,比如标量的基本运算以及数组元素的操作等。标量基本运算操作主要包括:

 

 算术运算符 

我们设置变量 $a 为 10,$b 为 20,可以进行如下算术运算:

 

运算符

描述

实例

+

加法运算

$a + $b  结果为 30

-

减法运算

$a - $b  结果为 -10

*

乘法运算

$a * $b  结果为 200

/

除法运算

$b / $a  结果为 2

%

求余运算,整除后的余数

$b % $a  结果为 0

**

乘幂

$a**$b 结果为  10 的 20 次方


小试牛刀:

perl -e ' $a=10;$b=20;$c=$a+$b ;print "$c\n" '  

#输出:30

 

 赋值运算符 

我们设置变量 $a 为 10,$b 为 20,可以进行如下赋值运算:


运算符

描述

实例

=

简单的赋值运算符

$c = $a +  $b 将把 $a + $b 的值赋给 $c

+=

加且赋值运算符

$c += $a  相等于 $c = $c + $a

-=

减且赋值运算符

$c -= $a  相等于 $c = $c - $a

*=

乘且赋值运算符

$c *= $a  相等于 $c = $c * $a

/=

除且赋值运算符

$c /= $a  相等于 $c = $c / $a

%=

求模且赋值运算符

$c %= $a  相等于 $c = $c % a

**=

乘幂且赋值运算符

$c **= $a  相等于 $c = $c ** $a


小试牛刀:

perl -e ' $a=10;$b=20;$b-=$a ; print "$b\n" '   

#输出:10

 

 比较运算符 

我们设置变量 $a 为 10,$b 为 20,可以进行如下比较运算:

 

运算符

描述

实例

==

检查两个操作数的值是否相等

($a == $b)  为 false

!=

检查两个操作数的值是否相等

($a != $b)  为 true。

检查左操作数的值是否大于右操作数的值  

($a >  $b) 返回 false。

检查左操作数的值是否小于右操作数的值  

($a <  $b) 返回 true。

>=

检查左操作数的值是否大于或等于右操作数的值

($a >=  $b) 返回 false。

<=

检查左操作数的值是否小于或等于右操作数的值

($a <=  $b) 返回 true。

 

小试牛刀:

perl -e ' $a=10;$b=20; print "Hello,world!\n"if($a<=$b) '  

#输出:Hello,world!

 

PS: cmd if(condition)是一个判断语句,表明“如果()中的condition为true就执行前面的cmd命令”,因为10<=20为true,所以会执行print命令,输出:Hello,world!

 

 逻辑运算符 

我们设置变量 $a 为 true, $b 为 false,进行如下逻辑运算:

 

运算符

描述

实例

and

逻辑与运算符符。如果两个操作数都为  true,则条件为 true。

($a and  $b) 为 false。

&&

C  风格的逻辑与运算符符。如果两个操作数都为 true,则条件为 true

($a  && $b) 为 false。

or

逻辑或运算符。如果两个操作数中有任意一个非零,则条件为  true。

($a or $b)  为 true。

||

C  风格逻辑或运算符。如果两个操作数中有任意一个非零,则条件为 true。

($a || $b)  为 true。

not

逻辑非运算符。用来反转操作数的逻辑状态。如果条件为  true,则逻辑非运算符将使其为 false。

not($a and  $b) 为 true。

 

小试牛刀:

perl -e ' $a="ture";$b="false"; print"Hello, everyone!\n" if($a || $b) '

#输出:Hello, everyone!

 

 位运算 

设置 $a =60,$b =13,进行如下位运算操作:

#60对应二进制为"00111100"

#13对应二进制为"00001101"

 

运算符

描述

实例

&

如果同时存在于两个操作数中,二进制  AND 运算符复制一位到结果中。

($a &  $b) 将得到 12,二进制为 0000 1100

|

如果存在于任一操作数中,二进制  OR 运算符复制一位到结果中。

($a | $b)  将得到 61 ,二进制为 0011 1101

^

如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。

($a ^ $b)  将得到 49,二进制为 0011 0001

~

二进制补码运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0。

(~$a ) 将得到  -61 ,二进制为 1100 0011 ,一个有符号二进制数的补码形式。

<< 

二进制左移运算符。左操作数的值向左移动右操作数指定的位数。

$a  << 2 将得到 240 ,二进制为 1111 0000

>> 

二进制右移运算符。左操作数的值向右移动右操作数指定的位数。

$a  >> 2 将得到 15 ,二进制为 0000 1111


小试牛刀:

perl -e ' $a=60;$b=13; $c=$a & $b; print "$c\n" '  

#输出:12


 

4

数组元素基本操作


创建数组

数组变量一般可以通过列表进行赋值,可以将元素放在括号内,也可以用 qw 定义数组。例如:

@array = (1, 2, 'Hello');

@array = qw/这是 一个 数组/;

 

添加和删除数组元素

如果想对数组里面的元素进行添加或者删除,可以通过一些特定的函数来实现:

 

序号

类型和描述

1

push  @ARRAY, LIST  将列表的值放到数组的末尾

2

pop @ARRAY  弹出数组最后一个值,并返回它

3

shift  @ARRAY  弹出数组第一个值,并返回它。数组的索引值也依次减一。

4

unshift  @ARRAY, LIST  将列表放在数组前面,并返回新数组的元素个数。



切割数组

我们还可以切割一个数组,并返回切割后的新数组:

 

#!/usr/bin/perl

@sites =qw/google taobao runoob weibo qq facebook/;

@sites2 =@sites[3,4,5];

print"@sites2\n";

 

执行结果:weibo qq facebook

 

split和jion操作

split和join是常用的数组操作。Perl语言中的split 函数可以将字符串转切割为数组,因此split也被称为“切割函数”,例如:

 

$str ="A:B:C";

my @arr =split/:/,$str;      #@arr = qw(A B C)

 

PS: 用split函数将字符串"A:B:C"以":"为分隔符进行切割,并赋值给数组@arr;

 

而join函数功能则正好相反,它可以将数组连接成字符串,因此join也被称为“胶水函数”,例如:

 

@arr =qw(A B C)

$str =join(",",@arr);         #$str="A,B,C"

 

PS: 用join函数将数组qw(A B C) 以","为连接符进行粘连,并赋值给标量$str;

 

foreach和each操作

foreach函数可以遍历数组所有元素,例如:

 

 foreach my $rock(qw(bedrock slate lava)){

      print "One rock is $rock\.\n";

   }

 

运行结果:

 

One rock isbedrock.

One rock isslate.

One rock islava.

 

然而与foreach不同的是,each函数在每一次被调用时,会返回数组中下一个元素所对应的索引和元素的值,例如:

 

my @rocks=qw(bedrock slate lava);

while(my ($index,$value)=each@rocks) {

      print "$index :$rocks[$index]\n";

   }

 

运行结果:

 

0 : bedrock

1 : slate

2 : lava

 

PS: while(condition){cmd}是一个循环控制语句,表示“如果()中的condition为true就一直执行{}中的cmd命令”,each @rocks命令会依次获取@rocks中每个元素的索引和元素的值并分别赋值给($index,$value)这两个变量,直到所有元素被遍历。

 

reverse和sort操作

reverse函数会读取列表的值并按相反的次序返回该列表,例如:

 

my @array =(1,2,3,4);

my @rev =reverse @array; 

print join(",",@rev);        #输出:4,3,2,1

 

sort函数则会对数组元素进行排序,例如:


my @array =(1,2,3,4);

@SORT = sort@array;                               #默认按字典顺序排序, @SORT=qw(1 2 3 4)

@SORT = sort{$a <=> $b} @array;           #按数字大小排序, @SORT=qw(1 2 3 4)

@SORT = sort{$b cmp $a} @array;          #按字典逆序排序, @SORT=qw(4 3 2 1)

print "@SORT\n";                                     #输出:4 3 2 1


 

scalar函数

scalar 函数可以返回数组元素个数,例如:

 

my @arr =(1,2,3,4);

print scalar(@arr);         # 输出:4

  

本文尽量精简的介绍了Perl语言的基本知识、基本数据结构以及变量常用的操作,并配上简单的示例供大家练习巩固,篇幅所限,难以具体展开,谨以此文,送与初入门perl语言的朋友们。


下一节课我们将学习:哈希和子函数,敬请大家关注!

 


参考资料:

《Perl语言入门 第六版(中文版)》

http://www.runoob.com/perl/perl-tutorial.html

http://www.runoob.com/try/runcode.php?filename=HelloWorld&type=perl

 





 

【完】



作者原创作品,未经授权禁止转载!

扫码关注,获取更多精彩内容

关注公众号后:


回复文字:好好学习,收听喜马拉雅FM电台栏目《一分钟听懂NGS基础概念》,让生信分析不再遥不可及。


回复文字:果然科学,给你看一篇好玩的科普文章。