2.1 数据类型(3)
2.1.7 单元数组类型
1.概述
单元(Cell)数组是一种无所不包的广义矩阵。组成单元数组的每一个元素称为一个单元。每一个单元可以包括一个任意数组,如数值数组、字符串数组、结构体数组或另外一个单元数组,因而每一个单元可以具有不同的尺寸和内存占用空间。
注意:和一般的数值数组一样,单元数组的维数不受限制,可以是一维、二维或多维。
MATLAB中使用单元数组的目的在于,它可以把不同类型的数据归并到一个数组中。
注意:单元数组的创建有两种方法:使用赋值语句创建单元数组和利用cell函数创建空单元数组。
(1)使用赋值语句创建单元数组。与一般数组有所不同的是,单元数组使用花括号“{}”来创建,使用逗号“,”或空格来分隔每一个单元,使用分号“;”来分行。
例2-18:创建单元数组。
在命令行窗口中输入:
clear C = {'x',[1;3;6];10,pi} whos C
程序运行结果如下:
C = 2×2 cell 数组 {'x' } {3×1 double} {[10]} {[ 3.1416]} Name Size Bytes Class Attributes C 2x2 458 cell
(2)利用cell函数创建空单元数组。
cell函数的调用格式如下:
cellName = cell(m,n)
该函数创建一个m×n的空单元数组,其每一个单元均为空矩阵。
例2-19:创建空单元数组。
在命令行窗口中输入:
clear a = cell(2,2) b = cell(1) whos
程序运行结果如下:
a = 2×2 cell 数组 {0×0 double} {0×0 double} {0×0 double} {0×0 double} b = 1×1 cell 数组 {0×0 double} Name Size Bytes Class Attributes a 2x2 32 cell b 1x1 8 cell
同一般的数值数组一样,单元数组的内存空间也是动态分配的。因此,使用cell函数创建空单元数组的主要目的是为该单元数组预先分配连续的存储空间,以节约内存占用,提高执行效率。
2.单元数组的寻访
在单元数组中,单元和单元中的内容是两个不同范畴的东西,因此,寻访单元和单元中的内容是两种不同的操作。MATLAB为上述两种操作设计了相对应的操作对象:单元外标识(Cell Indexing)和单元内编址(Content Addressing)。
对于单元数组C,C(m,n)指的是单元数组中第m行第n列的单元,而C{m,n}指的是单元数组中第m行第n列单元中的内容。
例2-20:单元数组的寻访。
在命令行窗口中依次输入以下命令:
clear C = {3, [4 7;6 6;80 9], 'string';sin(pi/8),3 > 10, 'code'} unitVal_1 = C(2,2) class(unitVal_1) unitVal_2 = C{2,2} class(unitVal_2)
依次得到的结果如下:
C = 2×3 cell 数组 {[ 3]} {3×2 double} {'string'} {[0.3827]} {[ 0]} {'code' } unitVal_1 = 1×1 cell 数组 {[0]} ans = 'cell' unitVal_2 = logical 0 ans = 'logical'
3.单元数组的操作
单元数组的操作包括合并、删除单元数组中的指定单元、改变单元数组的形状等。
(1)单元数组的合并。
例2-21:单元数组的合并。
在命令行窗口中依次输入以下命令:
clear a{1,1} = 'cellclass'; a{1,2} = [1 2 2]; a{2,1} = ['a','b','c']; a{2,2} = [9 5 6]; a b = {'Jan'} c = {a,b}
得到的结果如下:
a = 2×2 cell 数组 {'cellclass'} {1×3 double} {'abc' } {1×3 double} b = 1×1 cell 数组 {'Jan'} c = 1×2 cell 数组 {2×2 cell} {1×1 cell}
(2)单元数组中指定单元的删除。
如果要删除单元数组中指定的某个单元,则只需要将空矩阵赋给该单元,即:
C{m,n} = []
例2-22:有一个单元数组C,删除其中的某个单元。
在命令行窗口中依次输入下列命令:
clear C = {ones(3), 'Hello,World',zeros(5),[20,4,6]} C{1,4} = []
得到的结果如下:
C = 1×4 cell 数组 {3×3 double} {'Hello,World'} {5×5 double} {1×3 double} C = 1×4 cell 数组 {3×3 double} {'Hello,World'} {5×5 double} {0×0 double}
(3)使用reshape函数改变单元数组的形状。
reshape函数的调用格式为:
trimC = reshape(C,M,N)
该函数将单元数组C改变成一个具有M行N列的新单元数组。
例2-23:将例2-22中的单元数组C(1×4)改变成newC(4×1)。
在命令行窗口中输入:
newC = reshape(C,4,1)
得到的结果如下:
newC = 4×1 cell 数组 {3×3 double } {'Hello,World'} {5×5 double } {0×0 double }
2.1.8 map容器类型
1.map容器类型及map类概述
map的本意是映射,就是可以将一个量映射到另一个量。比如将一个字符串映射为一个数值,则该字符串就是map的键(key),数值就是map的数据(value)。因此,可以将map容器理解为一种快速查找数据结构的键。
对一个map元素进行寻访的索引称为“键”。一个键可以是以下任何一种数据类型:
● 1×N字符串。
● 单精度或双精度实数标量。
● 有符号或无符号标量整数。
这些键和其对应的数据存储在map中。一个map的每一个条目都包括唯一的键和相对应的数据。map中存储的数据可以是任何类型的,包括数值类型、字符或字符串类型、结构体类型、单元类型或其他map。
一个map是MATLAB类的一个对象。map类的所有对象具有3种属性,如表2-10所示。用户不能直接对这些属性进行修改,但可以通过作用于map类的函数进行修改。
表2-10 map类的属性
属性 |
说明 |
默认值 |
Count |
无符号64位整数,表示map对象中存储的key/value对的总数 |
0 |
KeyType |
字符串,表示map对象中包括的key的类型 |
char |
ValueType |
字符串,表示map对象中包括的数据类型 |
any |
map类的属性的查看方法为map名+小数点“.”+map的属性名。例如,为了查看mapW对象包括的数据类型,需要使用mapW.ValueType。
2.创建map对象
map是一个map类中的对象,由MATLAB中名为“容器”的一个包来定义,可以通过构造函数来创建,其创建方法如下:
mapObj = containers.Map({key1,key2,…},{val1,val2,…})
当键和值是字符串时,需要对上述语法稍作变更,即:
mapObj = containers.Map({'key1', 'key2',…},{val1,val2,…})
例2-24:创建一个名为schedulemap的map对象来存储如表2-11所示的课程表。
表2-11 课程表
星期一 |
星期二 |
星期三 |
星期四 |
星期五 |
数学 |
语文 |
历史 |
地理 |
生物 |
创建过程如下:
clear schedulemap = containers.Map({'Monday','Tuesday','Wednesday','Thursday','Friday'},{'Maths','Chinese','History','Geography','Biology'})
得到的结果如下:
schedulemap = Map - 属性: Count: 5 KeyType: char ValueType: char
此外,map对象的创建可以分为两个步骤:首先创建一个空map对象;然后使用keys和values方法对其内容进行补充。空map对象的创建方法如下:
newMap = containers.Map()
得到的结果如下:
newMap = Map - 属性: Count: 0 KeyType: char ValueType: any
3.查看/读取map对象
(1)查看map对象。
map对象中的每个条目包括两个部分:一个唯一的键及其对应的值。可以通过使用keys函数查看map对象中包含的所有键;通过values函数查看所有的值。
例2-25:查看例2-24中创建的map对象。
在命令行窗口中依次输入:
keys(schedulemap) values(schedulemap)
得到的结果如下:
ans = 1×5 cell 数组 {'Friday'} {'Monday'} {'Thursday'} {'Tuesday'} {'Wednesday'} ans = 1×5 cell 数组 {'Biology'} {'Maths'} {'Geography'} {'Chinese'} {'History'}
(2)读取map对象。
在创建好一个map对象后,用户可以对其进行数据的寻访。寻访指定键(keyName)所对应的值(valueName)使用的格式如下:
valueName = mapName(keyName)
当键名是一个字符串时,需使用单引号将键名括起来。
例2-26:通过使用键名访问例2-24中创建的schedulemap对象中的内容。
在命令行窗口中输入:
course = schedulemap('Wednesday')
得到的结果如下:
course = 'History'
如果需要对多个键进行访问,则可以使用values函数,如:
values(schedulemap,{'Monday','Thursday'})
得到的结果如下:
ans = 1×2 cell 数组 {'Maths'} {'Geography'}
提示:在对多个键进行访问时,不能像在其他数据类型中那样使用冒号“:”,这将导致错误的产生。例如输入:
schedulemap('Monday':'Thursday')
结果弹出如下错误信息:
警告:冒号操作数必须为实数标量。
4.编辑map对象
(1)从map对象中删除keys/values对。
用户可以使用remove函数从map对象中删除keys/values对,该函数的调用格式为:
remove('mapName','keyName')
式中,mapName和keyName分别为map对象名称及需要删除的键名。执行该命令后,MATLAB系统删除指定的键名及其相对应的值。
例2-27:删除schedulemap对象中的“星期四”及其对应的科目。
在命令行窗口中依次输入:
schedulemap = containers.Map({'Monday','Tuesday','Wednesday','Thursday','Friday'},{'Maths','Chinese','History','Geography','Biology'}) newMap = containers.Map() remove(schedulemap,'Thursday') keys(schedulemap) values(schedulemap)
得到的结果如下:
schedulemap = Map - 属性: Count: 5 KeyType: char ValueType: char newMap = Map - 属性: Count: 0 KeyType: char ValueType: any ans = Map - 属性: Count: 4 KeyType: char ValueType: char ans = 1×4 cell 数组 {'Friday'} {'Monday'} {'Tuesday'} {'Wednesday'} ans = 1×4 cell 数组 {'Biology'} {'Maths'} {'Chinese'} {'History'}
(2)添加keys/values对。
当用户向一个map对象中写入新元素的值时,需要提供键名,而且该键的类型必须和map中的其他键一致。该操作的调用格式为:
existingMapObj(newKeyName) = newValue
例2-28:为schedulemap对象添加“星期六”及其对应的科目“public elective course”。
在命令行窗口中依次输入:
schedulemap('Saturday') = 'public elective course' keys(schedulemap) values(schedulemap)
得到的结果如下:
schedulemap = Map - 属性: Count: 5 KeyType: char ValueType: char ans = 1×5 cell 数组 {'Friday'} {'Monday'} {'Saturday'} {'Tuesday'} {'Wednesday'} ans = 1×5 cell 数组 {'Biology'} {'Maths'} {'public elective…'} {'Chinese'} {'History'}
(3)修改keys。
如果需要在保持值不变的情况下对键名进行更改,则首先要删除键名和其对应的值,然后再添加一个有正确键名的新条目。
例2-29:根据例2-28中的schedulemap对象的结果,修改“星期六”及其对应的科目“公共选修课”为“星期天”及其对应的科目“MBA”。
在命令行窗口中依次输入:
remove(schedulemap,'Saturday'); schedulemap('Sunday') = 'MBA'; keys(schedulemap) values(schedulemap)
程序运行结果如下:
ans = 1×5 cell 数组 {'Friday'} {'Monday'} {'Sunday'} {'Tuesday'} {'Wednesday'} ans = 1×5 cell 数组 {'Biology'} {'Maths'} {'MBA'} {'Chinese'} {'History'}
(4)修改values。
通过赋值操作,覆盖原有的值,即可对map对象中的值进行修改。
例2-30:修改“星期一”的科目为“英语”。
在命令行窗口中依次输入:
schedulemap('Monday') schedulemap('Monday') = 'english'; keys(schedulemap) values(schedulemap)
程序运行结果如下:
ans = 'Maths' ans = 1×5 cell 数组 {'Friday'} {'Monday'} {'Sunday'} {'Tuesday'} {'Wednesday'} ans = 1×5 cell 数组 {'Biology'} {'english'} {'MBA'} {'Chinese'} {'History'}