《MATLAB程式设计与应用结构阵列.ppt》由会员分享,可在线阅读,更多相关《MATLAB程式设计与应用结构阵列.ppt(24页珍藏版)》请在三一办公上搜索。
1、MATLAB 程式設計與應用結構陣列,張智星(Roger Jang)http:/mirlab.org/jang台大資工系 多媒體檢索實驗室,13-1結構陣列的建立,每一個結構陣列(Structure Array)可以包含多個元素,每一個元素可以看成是一筆資料。因此每個元素(或每筆資料)可以包含數個欄位(Fields),而每個欄位可包含不同型態的資料。例如一個包含學生個人資料的結構陣列,可能含有的欄位是 name(學生姓名)、id(學號)、scores(小考成績)等。,結構陣列之範例一,要建立一個結構陣列,可在指令列直接輸入各個欄位的值。範例13-1:struct01.mclear studen
2、t%清除 student 變數student.name=洪鵬翔;%加入 name 欄位student.id=mr871912;%加入 id 欄位student.scores=58,75,62;%加入 scores 欄位student%秀出結果student=name:洪鵬翔 id:mr871912 scores:58,75,62此時 student 即代表一個結構陣列的第一個元素,或是第一筆資料。,結構陣列之範例二,範例13-2:struct02.mclear student%清除 student 變數student.name=洪鵬翔;%加入 name 欄位student.id=mr87191
3、2;%加入 id 欄位student.scores=58,75,62;%加入 scores 欄位%以下是新加入的第二筆資料student(2).name=邱中人;student(2).id=mr872510;student(2).scores=25,36,92;student%秀出結果student=1x2 struct array with fields:Name Id scoresdent=1x2 struct array with fields:Name Id scores,結構陣列之範例二,此時 student 即代表一個 12 的結構陣列。由於此結構陣列已漸趨複雜,MATLAB 並不
4、將所有欄位值印出。欲顯示某元素的特定欄位值,可輸入明確的敘述,例如 student(2).scores 等。另一個建立結構陣列的方法,則是使用 struct 指令,其格式如下:structureArray=struct(field1,value1,field2,value2,.)其中 field1、field2、是欄位名稱,value1、value2、則是欄位所包含的資料。如果 value1、value2、為異質陣列(Cell Arrays,詳見第上一章),則 MATLAB 為依序將異質陣列的每個元素設定為每一個結構中相對應的欄位值,如以下範例。,結構陣列之範例三,範例13-3:struct0
5、3.m student=struct(name,張庭碩,張庭安,scores,50 60,60 70);student(1)%顯示 student(1)student(2)%顯示 student(2)ans=name:張庭碩scores:50 60ans=name:張庭安 scores:60 70在上述使用法中,張庭碩,張庭安 和 50 60,60 70 都是異質陣列,因此他們的每個元素會被依次設定到每個結構之中。但是如果其中有一個異值陣列的長度是1,那麼 MATLAB 會進行純量展開(Scalar Expansion)來自動補足,如以下範例。,結構陣列之範例四,範例13-4:struct04
6、.mstudent=struct(name,張庭安,scores,50 60,90 100);student(1)%顯示 student(1)student(2)%顯示 student(2)ans=name:張庭安 scores:50 60ans=name:張庭安 scores:90 100在上述範例中,張庭安可視為異質陣列的一個元素,因此在設定至 student 結構陣列時,MATLAB 會進行純量展開,將張庭安分別設定到 student 的兩個元素的 name 欄位值。,結構陣列之範例五,結構陣列可以是巢狀式(Nested)的,也就是說,結構陣列的欄位可是另一個結構陣列,我們可以藉此產生複
7、雜的資料結構範例13-5:struct05.mstudent=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).courseans=1x2 struct array with fields:titlecredits,13-2 取用及改變結構陣列的資料
8、,student結構陣列,student(1),student(2),student(3),.name=banny.scores=85,80,92,78,.name=joey.scores=80,85,90,88,.name=batty.scores=88,82,90,80,範例13-6:buildStruct01.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)=stru
9、ct(name,Betty,scores,88,82,90,80);上述的 student 結構陣列,可圖示如下:,struct2cell指令,欲取用結構陣列中所有元素內所有欄位的資料,可用 struct2cell 指令,例如:values=struct2cell(student)values(:,:,1)=Banny 1x4 doublevalues(:,:,2)=Joey 1x4 doublevalues(:,:,3)=Betty 1x4 double請注意,傳回的 values 是一個異質陣列。一般而言,若輸入 struct2cell 指令的結構變數維度為 mn,且包含 p 個欄位,則傳
10、回異質陣列的維度為 pmn。(在上例中,p=2,m=1,n=3。),改變結構陣列內容,在結構陣列中,我們可以使用句點(”.”)來找出某一筆資料內的某一個特定欄位值,例如我們僅想看看第二個學生是誰,此時我們可以輸入:studentName=student(2).name studentName=Joey在上例中,在此一學生結構陣列的第二陣列元素 student(2)之後加上一點,再接上姓名欄位名稱 name,即可取用此學生的實際姓名資料 Joey,本例中進一步再將取出的學生姓名 Joey 儲存在使用者自設的變數 studentName 之後顯示於螢幕上。類似取用結構陣列個別欄位資料內容的作法,我
11、們可以改變結構陣列中個別欄位的資料內容,例如:student(2).name=Alex;在上例中,student(2)的姓名已由原先的 Joey 改變為 Alex。,cat指令,MATLAB 提供了 cat 指令,以達到並排欄位值的目的,其語法為:A=cat(dim,structureField)其中,dim 代表並排後所改變的維度。例如,欲將小考成績左右(水平)並排,可輸入:cat(2,student.scores)%2 代表左右並排以改變直行的維度ans=85 80 92 78 80 85 90 88 88 82 90 80 欲將小考成績上下(垂直)並排,可輸入:cat(1,student
12、.scores)%1 代表上下並排以改變橫列的維度ans=85 80 92 78 80 85 90 88 88 82 90 80,計算平均,在進行並排時,必須確認被並排的欄位值有相同的行數(上下並排)或列數(左右並排),否則就會因為維度不和而產生錯誤訊息。若要計算每次考試(共四次)的平均分數,可輸入:average1=mean(cat(1,student.scores)average1=84.3333 82.3333 90.6667 82.0000若要計算每位學生(共三位)的平均分數,可輸入下列運算式,但注意運算式後面單引號的使用代表矩陣的轉置(Transpose),因為 mean 指令預設是
13、對矩陣的每一直行進行平均值運算:average2=mean(cat(1,student.scores)average2=83.7500 85.7500 85.0000,並排運算,由於並排運算常被用到,MATLAB 又提供下列兩種方法方括弧運算:可以左右合併結構陣列中相同欄位的數值矩陣,產生一個新的數值矩陣。大括弧運算:可以左右合併結構陣列中相同欄位的資料,產生一個異值矩陣。若要把 scores 欄位值進行左右合併,可以輸入如下:allScores=student.scoresallScores=85 80 92 78 80 85 90 88 88 82 90 80 若要把 name 欄位值抽取
14、出來,形成由字串組成的異值陣列,可以輸入如下:allNames=student.nameallNames=Banny Alex Betty,結構陣列之範例七,範例13-7:printStruct01.mclear 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(studen
15、t%g:%sn,i,student(i).name);end,student 1:張庭碩student 2:鍾書蓉student 3:黃念中,取得及改變欄位資料,亦可用 getfield及setfield來取得及改變一個欄位的資料其指令使用格式如下:fieldValues=getfield(structureArray,arrayIndex,field,fieldIndex)newStructure=setfield(structureArray,arrayIndex,field,fieldIndex)輸入下列運算式即可取得第二位學生的第一次小考成績:score3=getfield(stude
16、nt,2,scores,1)上述 MATLAB 敘述可簡化為 score3=student(2).scores(1);若欲改變第二位學生的第三次小考成績,可輸入如下:student=setfield(student,2,scores,1,75);上述敘述亦可簡化為 student(2).scores(1)=75;,結構陣列之範例八,範例13-8:deal01.mmyStruct=struct(name,Tim,Annie,age,10,13);myStruct.name=deal(Roger,Tom);fprintf(myStruct(1).name=%sn,myStruct(1).name)
17、;fprintf(myStruct(2).name=%sn,myStruct(2).name);myStruct(1).name=RogermyStruct(2).name=Tom,13-3取用及改變結構陣列的欄位,使用 fieldnames 指令可傳回一個結構陣列的所有欄位名稱,例如:範例13-9:fieldNames01.mstudent=struct(name,Roland,scores,80,90);allFields=fieldnames(student)allfields=name scores 其傳回的結果是一個字串異質陣列(Cell Array of Strings),包含了
18、student 的所有欄位。欲增加一個新的欄位,直接將此欄加入於任一陣列元素即可,結構陣列之範例十,範例13-10:addField01.mclear student%清除 student 變數student=struct(name,Roland,scores,80,90);student(2).age=20;%加入新欄位student(1)%顯示 student(1)student(2)%顯示 student(2)ans=name:Roland scores:80 90 age:ans=name:scores:age:20由上述結果可看出,MATLAB 會將此新欄位加入其他元素,並設定其預設
19、值為(空矩陣)。,結構陣列之範例十一,範例13-11:rmField01.mstudent=struct(name,Roland,scores,80,90)student2=rmfield(student,scores)%刪除 scores 欄位 student=name:Roland scores:80 90student2=name:Roland,13-4 其他相關指令,我們可用 isstruct 指令來測試某個變數是否為結構陣列,如下:範例13-12:isstruct01.ms=struct(name,Tim,Ann,scores,1 3 5,2 4 6);isstruct(s)ans=
20、1 isfield 指令則可用於測試某結構陣列是否含一特定欄位,例如:範例13-13:isstruct02.ms=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(s,name)=1isfield(s,height)=0在上例中,因 s 並不包含“height”的欄位,故回傳數值 0。,結構陣列之範例十四,我們可用 cell2struct 指令來將異質陣列轉換成結構陣
21、列,例如:範例13-14:cell2struct01.mfields=name,age;values=Tim,9;Annie,6;s=cell2struct(values,fields,2);s(1)%印出第一筆資料s(2)%印出第二筆資料ans=name:Tim age:9ans=name:Annie age:6在上例中,運算式s=cell2struct(values,fields,2)代表指令 cell2struct 將根據陣列變數 fields 的資料為欄位名稱,並以 values 的第二個維度來對應欄位名稱 fields,來產生一個結構陣列 s。,結構陣列之範例十五,如果以 value
22、s 的第一個維度來對應欄位名稱 fields,結果如下:範例13-15:cell2struct02.mfields=name,age;values=Tim,9;Annie,6;s=cell2struct(values,fields,1);s(1)%印出第一筆資料s(2)%印出第二筆資料ans=name:Tim age:Annieans=name:9 age:6,結構陣列之範例十六,dir 指令傳回一結構陣列,包含現在目錄(或資料夾)下各種資訊範例13-16:dir01.mdirinfo=dir(matlabroot)%字串變數 matlabroot 代表 MATLAB 根目錄dirinfo=19x1 struct array with fields:name date bytes isdir由上可知,dirinfo 為一結構陣列,內含在 MATLAB 根目錄下所含檔案或其他目錄的資訊,即其名稱(name),產生日期(date),大小(bytes),及是否為目錄(isdir)等。,