没有合适的资源?快使用搜索试试~ 我知道了~
MATLAB常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。除了这些基本数据类型,MATLAB还有很多其它的数据类型不为人熟悉,这些数据类型在编程中也非常有用。MATLAB高级数据类型系列旨在向大家介绍它们:比如 containers.Map,tables,enumeration和time series等等,它们为什么有用,用来解决什么问题,并且怎样在科学工程计算使用。首先介绍 containers.Map 数据类型。
资源推荐
资源详情
资源评论
MATLAB 常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。
除了这些基本数据类型,MATLAB 还有很多其它的数据类型不为人熟悉,这些数据类型在编
程中也非常有用。MATLAB 高级数据类型系列旨在向大家介绍它们:比如 containers.Map,
tables,enumeration 和 time series 等等,它们为什么有用,用来解决什么问题,并且怎样
在科学工程计算使用。首先介绍 containers.Map 数据类型。
containers.Map 简介
MATLAB 中最具代表性的高级数据类型是 containers.Map,我们可以把它叫做映射表。它和
函数映射有些类似,比如函数映射的定义是:
F(x) = Y
针对每一个 X,都有一个唯一的 Y 与之对应,反之不一定。如图 Fig.1 所示。和函数映射
相似,映射表用来形容键(Key)和键值(Key Value)之间的一一对应关系。每个 Key 都
是独一无二的,且只能对一个 Key Value。如图 Fig.2 所示。
Fig.1 函数映射关系
Fig.2 containers.Map 类的映射示意图
数组,元胞和结构体的局限性
开始我们先介绍一下数组,元胞数组和结构体的局限性,为什么有的时候这些基本的数据类
型无法满足程序的要求,换句话说,我们为什么需要 containers.Map 数据结构。假设要用
MATLAB 来记录电话号码簿中数据,比如表 Table.1 所示:
Table.1 电话号码簿
姓名
电话号码
Abby
5086470001
Bob
5086470002
Charlie
5086470003
先讨论数组,因为电话号码簿中既含有数字,又含有字符串,而数组中只能存放 Double 类
型的数据,所以没有办法用数组直接记录电话号码薄中的内容。 再试试元胞数组,我们在
第 1 行预先声明一个 3 X 3 的元胞数组,然后在 2-4 行按顺序填放号码簿的内容。
% 元胞数组初始化
addressBook = cell(3,1); % 预分配大小是 MATLAB 编程的好习惯
addressBook{1} = {'Abby', '5086470001'};
addressBook{2} = {'Bob' , '5086470002'};
addressBook{3} = {'Charlie', '5086470003'};
需要的时候,可以通过 for 循环访问其中的内容,比如:
for iter = 1:length(addressBook) % 元胞数组的遍历
addressBook{iter} % 通过 Index 访问元胞中的内容
end
但是按照顺序遍历电话号码簿没有什么实际用处,号码簿的主要功能应该是提供查找的功能
才是。比如要想查询 Charlie 的电话号码,我们希望程序最好可以写成如下这样:
CharlieNum = addressBook{'Charlie'} % 提示:这是错误的写法
或者
CharlieNum = addressBook.Charlie % 提示:这是错误的写法
但是元胞数组的值只能通过 Index 去访问内容,不支持如上的访问方式。所以为了找到
Charlie 的电话号码,程序不得不遍历元胞中的所有内容,取出每一个元胞元素的第一列的
字符串做比较,如果名字等于 Charlie,则输出电话号码:
% 使用 for 循环查找
for iter = 1:length(addressBook)
if strcmp(addressBook{iter}{1},'Charlie')
addressBook{iter}{2} % 如找到则输出电话号码
break;
end
end
当然还有其他的方式来盛放电话号码簿,比如把电话和名字分别存到到两个元胞数组中去
names = {'Abby','Bob','Charlie'}; % 用元胞放号码
numbers = {'5086470001','5086470002','5086470001'}; % 用元胞放名字
ind = find(strcmp(names,'Charlie')); % strcmp 接受向量的输入 返回 Logical 数组
% find 紧接着找出逻辑数组中非零元素的 Index
numbers{ind}
其中第 3 行 strcmp 接受元胞作为输入,在其中寻找 Charlie,find 函数将返回 Charlie 所在
的位置,这样的方式比使用 for 循环要快,但无一例外的是,两种方法都要从头开始遍历一
个数组,终究来说是慢的。 除查找性能慢外,使用元胞盛放电话号码簿类型的数据还有其
它缺点:
� 无法方便的验证重复数据。电话号码簿要求每一个人的名字都是独一无二的,所以
在数据录入的时候要防止姓名的重复,但是我们没有其它办法知道某名字是否已经被使
用过了,除非在每次输入的时候都对整个元胞里的内容做遍历比较。
� 无法方便地添加内容。如果电话号码簿中的记录需要不断地增长,但是我们没有办
法在一开始就估计出其大概的数量,于是无法有效的预先分配内存,所以添加数据时,
一旦超过预先分配的量,MATLAB 就要重新分配内存了。
� 无法方便地删除内容。如果我们要从元胞中去掉某一记录,可以找到该记录,并把
该位置的元胞内容置空,但这并不会自动减小元胞数组的长度,如果 这样的删减操作
多了,元胞中会留下很多没有利用的空余位置。
� 不方便作为函数的参数,具体原因见 struct 的局限性.
最后我们再尝试一下用结构体盛放电话号码簿数据类型,struct 的赋值很简单,比如可以直
接赋值:
% 赋值方法 1
addressBook.Abby = '5086470001';
addressBook.Bob = '5086470002';
addressBook.Charlie = '5086470003';
或者:
% 赋值方法 2
addressBook = struct('Abby','5086470001','Bob','5086470002','Charlie','508647000
3')
方法 1 和方法 2 是等价的。 struct 数据类型的查找很方便,比如要查询 Charlie 的电话号码,
直接访问 struct 中的同名的 field 即可以了。
num = addressBook.Charlie
如果要查询的人名是一个变量, 我们可以使用 getfield 函数:
num = getfield(addressBook,name) % 其中 name 是变量
struct 盛放电话号码簿类型的数据,查询起来确实比元胞进步了不少,但还是有些不方便的
地方。 因为 struct 的 field 的名字要求必须是以字母开头,这是一个很大的局限,并不是所
有的类似电话号码簿的结构都可以用人名做索引,比如账户号码簿,股票代码等等,他们通
常是用数字开头的,比如图 Table.2 中的数据:
Table.2 深证股票代码
股票代码
股票名称
剩余11页未读,继续阅读
资源评论
小小哭包
- 粉丝: 1899
- 资源: 3846
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功