ch3Matlab数据结构.ppt
Matlab 数据结构,安徽工业大学数理学院侯为根,Matlab 数据结构,1)矩阵数组,3)字符与字符串数组,4)结构数组,5)元胞(异质)数组,2)多维数组,在 MATLAB 的数据型态中,向量可视为一维数组,矩阵可视二维数组,对于维数(Dimensions)超过 1 的数组则均可视为”多维数组”(Multidimesional Arrays,简称 M-D Arrays)。,1 多维数组的定义,多维数组,二维数组又简称矩阵,具有两个维数(Dimensions)行(Row)列(Column),列,行,二维数组(I),二维数组,可对应至一个 X-Y 二维平面坐标,图示如右:,将两个二维数组迭在一起,就形成第三个维度,此第三个维度称为”页”(Page),图示如下,页,列,页,行,三维数组(I),三维数组,可对应至一个 X-Y-Z 三维立体坐标,图示如右:,三维数组寻址,可以(行,列,页)定之。以维度为 342 的三维数组为例,其寻址方式可图示如下:,数组 A 是三维数组,其中 A(:,:,1)代表第一页的二维数组,A(:,:,2)代表第二页的二维数组。,三维数组,A(:,:,1),A(:,:,2),A(3,1,1),A(2,4,2),四维数组的第四个维度可视为”箱”(Box),而每个箱是由一个三维数组所组成,其寻址方式为(行,列,页,箱)。,可类推至 n 维数组,n 为任意自然数。,四维数组,一个 2235 的四维数组,可表示成 5 个箱,每个箱都由一个 223 的三维数组所组成,图标如下:,A=1 0 2 5;4 1 8 7;3 2 6 3;A(:,:,2)=3 5 4 1;2 6 2 1;4 2 3 0A(:,:,1)A(:,:,2),2 多维数组的建立,例1,建立一个简单的多维数组,可直接由 MATLAB 指令窗口内输入,上例是先建立一个二维数组A,再输入第二页的二维数组A(:,:,2),逐页输入二维数组的内容,即可建立三维数组。如果直接设定某一个新页的一个元素值,此时MATLAB会将此页其它未指定之元素直接设定为0,范例如下:,A=1 0 2 5;4 1 8 7;3 2 6 3;A(:,:,2)=3 5 4 1;2 6 2 1;4 2 3 0;A(2,1,3)=5,若要将数组 A 的第二页所有元素设为 7,可输入:A(:,:,2)=7,多维数组直接设定,例2:,A(:,:,1)A(:,:,2)A(:,:,3),对于较复杂的多维数组,可用 cat 指令来建立,其功能为”并排”数个数组,并可指定”并排”时所用的维度其指令格式如下:Z=cat(dim,A,B,C)A、B、C 为数组dim 是将 A、B、C 合并时所用到的维度。欲将矩阵 A 与 B 上下(垂直)并排,垂直并排多维数组,A=1 2;3 4;B=1 0;0 1;Z=cat(1,A,B)A;B,数字1表示将数组A与 B上下垂直并排,例3:,欲将数组 A 与 B 左右(水平)并排例4:,A=1 2;3 4;B=1 0;0 1;Z=cat(2,A,B),水平并排多维数组,数字 2 表示将数组 A 与 B 左右水平并排,将数组 A 与 B 迭起来,得到一个三维数组 例5:,A=1 2;3 4;B=1 0;0 1;Z=cat(3,A,B),数组堆栈,数字3表示将数组 A 与 B 重迭排成三维数组,所设定的 dim 值比数组 A、B、C的各自原先的“维度数”(Dimensionality)还要超出 2 或更多,MATLAB 会自动补上大小为 1 的维度此时数组 Z 的维度变为 2212 例6,A=1 2;3 4;B=1 0;0 1;Z=cat(4,A,B),Z(:,:,1,1),Z(:,:,1,2),cat自动补齐维数,数字 4 表示将数组 A 与 B 放在相邻的两“箱”,可用squeeze命令压缩孤维,S=squeeze(z),例7,MATLAB 可产生特殊用途的多维数组 要产生一个维度是 235 的随机数数组,可用 rand 指令,A=rand(2,3,5)A(:,:,1)A(:,:,2)A(:,:,3)A(:,:,4)A(:,:,5),随机数数组,许多用于向量和矩阵的数学运算,例如 sum、max、min、mean 等,也都可以用在多维数组。在使用这些指令时,我们必须指定这些指令的操作是在哪一个维度。,维度指定,范例7 A=1 1 1 1;2 2 2 2;3 3 3 3;B=0 0 0 0;1 1 1 1;1 2 3 4;Z=cat(3,A,B);,%将矩阵 A,B 迭成一个三维数组,3 多维数组的数学运算,S=sum(Z,1)%根据第一维度来对元素进行相加size(S)S2=sum(Z,2)%根据第二维度来对元素进行相加 S3=sum(Z,3)%根据第三维度来对元素进行相加,3 多维数组的数学运算,上述例中,矩阵 Z 的大小是 342,sum(Z,1)是根据第一个维度来进行相加,因此第一个维度值就会被被压成是 1,因此 size(S)所传回的值是 1,4,2,代表矩阵 S 的大小是 142sum(Z)的预设相加维度即是 1,因此 sum(Z)和 sum(Z,1)所得到的结果是一样的。,对第二个维度进行相加,可见下列范例,A=1 1 1 1;2 2 2 2;3 3 3 3;B=0 0 0 0;1 1 1 1;1 2 3 4;Z=cat(3,A,B);%将矩阵 A,B 迭成一个三维数组 S=sum(Z,2)%根据第二维度来对元素进行相加,例8,在上述范例中,sum(Z,2)是对第二个维度进行相加运算,因此所传回的矩阵 S 的维度是 312。,如果所要相加的维度只有单一维度,那么 sum 指令会对下一个维度进行相加的动作,sum(sum(Z)将会得到三维数组 Z 的每一页的总和,sum的累加,例9A=1 1 1 1;2 2 2 2;3 3 3 3;B=0 0 0 0;1 1 1 1;1 2 3 4;Z=cat(3,A,B);%将矩阵 A,B 迭成一个三维数组S=sum(sum(Z),与 sum 类似的指令还有 max、min、mean、median、mode、std、diff、sort 等,MATLAB 在第五版之后才支持的数据型态,将不同的数据型态储存于同一个数组之中,异质数组(Cell Arrays),主要功能,1、建立异质数组;2、显示异质数组;3、取用异质数组.,本节重点,异质数组(Cell Arrays)可储存各种不同型态的 MATLAB 数据Cell Arrays=“盒子数组”!?“异质”=“不同性质的数据型态”,建立异质数组-Cell Indexing,clear A(1,1)=This is the first cell.;A(1,2)=5+j*6,4+j*5;A(2,1)=1 2 3;4 5 6;7 8 9;A(2,2)=Tim;Chris,Ex:cell01.M,上例建立了一个二维异质数组A:2*2内容如下:,建立异质数组-Content Indexing,做法:矩阵()异质数组,Ex:cell02.m,A1,1=this is the first cell.;A1,2=5+j*6,4+j*5;A2,1=1 2 3;4 5 6;7 8 9;A2,2=Tim;Chris,结果同上例,建立异质数组 使用大括号,B=James Bond,1 2;3 4;5 6;pi,magic(5)C=rand(3),ones(2);zeros(5),randperm(4),第三种方法是直接用大括号一次把所有元素括起来,Ex:,对于异质数组的合并,大致上跟数组合并相同Ex:(B,C如上)M=B C%将异质数组 B 及 C 左右并排,异值数组的合并,若在 MATLAB 指令窗口内,直接呼叫异质数组的名称,MATLAB 并不直接显示异质数组各元素的值,,异质数组的内容显示,直接呼叫?=maybe not,Ex:A,只能显示各元素的数据型态及维度,A=1x23 char 1x2 double 3x3 double 2x1 cell,A1,1=this is the first cell.;A1,2=5+j*6,4+j*5;A2,1=1 2 3;4 5 6;7 8 9;A2,2=Tim;Chris;cellplot(A)%以图形的方式显示异质数组 A 的内部数据型态,Cellplot图标型态,cellplot 指令可将异质数组的内部数据型态,以图形的方式显示,Ex:cell03.m,celldisp(A)%显示异质数组 A 各个构成元素的实际内容,celldisp显示,Ex:,前提过建立异质数组的方法Content Indexing,其实也可以用来直接将异质数组 A 的各个构成元素内容一次全部显示出来,Content Indexing显示,用法:要查看A的内容,在MATLAB下直接输入:,A:%显示异质数组 A 的全部构成元素,1、直接取用异质数组的cell;2、取用异值数组的元素的内部构成单位;3、一次同时取用或删除多个元素;4、异质数组可以取代以逗点分开的变量列。,异质数组的内容取用,以下例子先建立一个异质数组 B,再取用其中第 1行、第 2 列的元素:,直接取用异质数组的cell,B=James Bond,1 2;3 4;5 6;pi,magic(5),F=B1,2%取用异质数组 B 的第 1行、第 2列的元素,直接取用异质数组的cell(cont),先用 Content Indexing 的方法,再直接加上一般矩阵的索引法,取用异值数组的元素的内部构成单位,例:G=B1,2(3,1),H=B(2,:)%取用异质数组 B 的第二行所有元素 B(1,:)=%删除异质数组 B 的第一行所有元素,同时取用或删除多个元素,如上述异质数组B,同理,亦可将之用于输出变数列:例:clear;F1:2=max(rand(5),取代以逗点分开的变数列,例:%先建立一个维数为 14 的异质数组F=2 3 5,1 2 3,Timmy,Annie F1:2,上例中,F1:2 会指向“2 3 5,1 2 2”可将之用于函数的输入变量列,例如:,plot(F1:2,-o),改变异质数组的大小事先预设(Pre-Allocate)空的异质数组测试某一变量是否为异质数组将一数值数组转换成异质数组将一结构数组的所有字段值转换成异质数组将异值数组转换为结构数组将一结构数组的某一字段值转换成异质数组,其它相关指令,结构数组,每一个结构数组(Structure Array)可以包含很多个元素,每一个元素可以看成是一笔数据。因此每个元素可以包含数个字段(Fields),而每个字段可包含各个不同型态的数据。例如一个包含学生个人数据的结构数组,可能含有的字段是 name(学生姓名)、id(学号)、scores(小考成绩)等。要建立此种结构,可在指令行直接输入个字段的值。,1、结构数组的建立,clear student%清除 student 变数 student.name=洪鹏翔;%加入 name 字段 student.id=mr871912;%加入 id 字段 student.scores=58,75,62;%加入 scores 字段 student%秀出结果,范例1:struct01.m,此时 student 即代表一个结构数组的第一个元素,或是第一笔数据。,clear student%清除 student 变数student.name=洪鹏翔;%加入 name 字段student.id=mr871912;%加入 id 字段student.scores=58,75,62;%加入 scores 字段%以下是新加入的第二笔数据student(2).name=邱中人;student(2).id=mr872510;student(2).scores=25,36,92;student%秀出结果,范例2:struct02.m,此时 student 即代表一个 12 的结构数组。由于此结构数组已渐趋复杂,MATLAB 并不将所有字段值印出。欲显示某元素的特定字段值,可输入明确的叙述,例如 student(2).scores 等。,另一个建立结构数组的方法,则是使用 struct 指令,其格式如下:structureArray=struct(field1,value1,field2,value2,.)其中 field1、field2、是字段名称,value1、value2、则是字段所包含的数据。如果 value1、value2、为异质数组(Cell Arrays,详见第上一节),则 MATLAB 为依序将异质数组的每个元素设定为每一个结构中相对应的字段值,如以下例3:,student=struct(name,张庭硕,张庭安,scores,50 60,60 70);student(1)%显示 student(1)student(2)%显示 student(2),例3:struct03.m,在上述使用法中,张庭硕,张庭安 和 50 60,60 70 都是异质数组,因此他们的每个元素会被依次设定到每个结构之中。但是如果其中有一个异值数组的长度是1,那么 MATLAB 会进行纯量展开(Scalar Expansion)来自动补足,如以下范例4:,clear student=struct(name,张庭安,scores,50 60,90 100);student(1)%显示 student(1)student(2)%显示 student(2),范例4:struct04.m,在上述范例中,”张庭安”可视为异质数组的一个元素,因此在设定至 student 结构数组时,MATLAB 会进行纯量展开,将”张庭安”分别设定到 student 的两个元素的 name 字段值。,student=struct(name,张庭硕,张庭安,scores,50 60,60 70);student(2).course(1).title=Web Programming;student(2).course(1).credits=2;student(2).course(2).title=Numerical Method;student(2).course(2).credits=3;student(2).course,结构数组可以是嵌套式(Nested)的,也就是说,结构数组的字段可是另一个结构数组,我们可以藉此产生复杂的数据结构,范例5:struct05.m,clear student%清除 student 变数student(1)=struct(name,Banny,scores,85,80,92,78);student(2)=struct(name,Joey,scores,80,85,90,88);student(3)=struct(name,Betty,scores,88,82,90,80);,取用及改变结构数组的数据,例6:buildStruct01.m,上述的 student 结构数组,可图标如下:,请注意,返回的 values 是一个异质数组。一般而言,若输入 struct2cell 指令的结构变量维数为 mn,且包含 p 个字段,则返回异质数组的维度为 pmn。(在上例中,p=2,m=1,n=3)。,Struct2cell指令,欲取用结构数组中所有元素内所有字段的数据,可用 struct2cell 指令,例如:values=struct2cell(student),在结构数组中,我们可以使用“句点”(”.”)来找出某一笔数据内的某一个特定字段值,例如我们仅想看看第二个学生是谁,此时我们可以输入:studentName=student(2).name,改变结构数组内容,在上例中,在此一学生结构数组的第二数组元素 student(2)之后加上一点,再接上姓名字段名称 name,即可取用此学生的实际姓名资料 Joey,本例中进一步再将取出的学生姓名 Joey 储存在使用者自设的变量 studentName 之后显示于屏幕上。,类似取用结构数组个别字段数据内容的作法,我们可以改变结构数组中个别字段的数据内容,例如:,student(2).name=Alex,在上例中,student(2)的姓名已由原先的 Joey 改变为 Alex。,cat(1,student.scores)%1 代表上下并排以改变行的维度,CAT指令,MATLAB 提供了 cat 指令,以达到并排字段值的目的,其语法为:,A=cat(dim,structureField),其中,dim 代表并排后所改变的维度。例如,欲将小考成绩左右(水平)并排,可输入,cat(2,student.scores)%2 代表左右并排以改变列的维度,欲将小考成绩上下(垂直)并排,可输入:,在进行并排时,必须确认被并排的字段值有相同的列数(上下并排)或行数(左右并排),否则就会因为维度不和而产生错误信息。若要计算每次考试(共四次)的平均分数,可输入:,计算平均,若要计算每位学生(共三位)的平均分数,可输入下列表达式,但注意表达式后面单引号的使用代表矩阵的转置(Transpose),因为 mean 指令是对矩阵的每一列进行平均值运算:,average1=mean(cat(1,student.scores),average2=mean(cat(1,student.scores),allNames=student.name,并排运算,由于并排运算常被用到,MATLAB 又提供下列两种方法,方括号运算:可以左右合并结构数组中相同字段的数值矩阵,产生一个新的数值矩阵。,大括号运算:可以左右合并结构数组中相同字段的数据,产生一个异值矩阵。,若要把 scores 字段值进行左右合并,可以输入如下:,allScores=student.scores,若要把 name 字段值抽取出来,形成由字符串组成的异值数组,可以输入如下:,clear student%清除 student 变数student(1)=struct(name,张庭硕,scores,85,80);student(2)=struct(name,钟书蓉,scores,80,85);student(3)=struct(name,黄念中,scores,88,82);for i=1:length(student)%打印出每个学生的名字 fprintf(student%g:%sn,i,student(i).name);end,例7:printStruct01.m,fieldValues=getfield(structureArray,arrayIndex,field,fieldIndex)newStructure=setfield(structureArray,arrayIndex,field,fieldIndex),取得及改变字段数据,亦可用 getfield及setfield来取得及改变一个字段的数据,其指令使用格式如下:,student(2).scores(1)=75,输入下列表达式即可取得第二位学生的第一次小考成绩:,score3=getfield(student,2,scores,1),上述 MATLAB 叙述可简化为,score3=student(2).scores(1);,若欲改变第二位学生的第三次小考成绩,可输入如下:,student=setfield(student,2,scores,1,75);,上述叙述亦可简化为,myStruct=struct(name,Tim,Annie,age,10,13);myStruct.name=deal(Roger,Sue);fprintf(myStruct(1).name=%sn,myStruct(1).name);fprintf(myStruct(2).name=%sn,myStruct(2).name);,例8:deal01.m,student=struct(name,Roland,scores,80,90);allFields=fieldnames(student),3、取用及改变结构数组的字段,使用 fieldnames 指令可返回一结构数组的所有字段,例如:,例9:fieldNames01.m,其返回的结果是一个字符串异质数组(Cell Array of Strings),包含了 student 的所有字段。,欲增加一个新的字段,直接将此栏加入于任一数组元素即可,clear student%清除 student 变数student=struct(name,Roland,scores,80,90);student(2).age=20;%加入新字段student(1)%显示 student(1)student(2)%显示 student(2),例10:addField01.m,student=struct(name,Roland,scores,80,90)student2=rmfield(student,scores)%删除 scores 字段,例11:rmField01.m,由上述结果可看出,MATLAB 会将此新字段加入其它元素,并设定其默认值为(空矩阵)。,4 其它相关指令,我们可用 isstruct 指令来测试某个变量是否为结构数组,如下:,例12:isstruct01.m,s=struct(name,Tim,Ann,scores,1 3 5,2 4 6);isstruct(s),s=struct(name,Tim,Ann,scores,1 3 5,2 4 6);fprintf(isfield(s,name)=%dn,isfield(s,name);fprintf(isfield(s,height)=%dn,isfield(s,height);,isfield 指令则可用于测试某结构数组是否含一特定字段,例如:,例13:isstruct02.m,在上例中,因 s 并不包含“height”的字段,故回传数值 0,我们可用 cell2struct 指令来将异质数组转换成结构数组,例如:,fields=name,age;values=Tim,9;Annie,6;s=cell2struct(values,fields,2);s(1)%显示第一个记录s(2)%显示第二个记录,例14:cell2struct01.m,在上例中,表达式s=cell2struct(values,fields,2)代表指令 cell2struct 将根据数组变量 fields 的数据为字段名称,并以 values 的第二个维度来对应字段名称 fields,来产生一个结构数组 s。,如果以 values 的第一个维度来对应字段名称 fields,结果如下:,fields=name,age;values=Tim,9;Annie,6;s=cell2struct(values,fields,1);s(1)%显示第一个记录s(2)%显示第二个记录,例15:cell2struct02.m,dir 指令传回一结构数组,包含现在目录(或数据夹)下各种信息,dirinfo=dir(matlabroot)%字符串变量 matlabroot 代表 MATLAB 根目录,例16:dir01.m,由上可知,dirinfo 为一结构数组,内含在 MATLAB 根目录下所含档案或其它目录的信息,即其名称(name),产生日期(date),大小(bytes),及是否为目录(isdir)等。,