基于元胞数据的多维数据传递机制

2016-01-24 02:28尹云旺2
北京测绘 2016年2期
关键词:数据类型元胞数组

王 珊 尹云旺2

(1.山东科技大学测绘科学与工程学院,山东 青岛266590;2.西安大地测绘股份有限公司,陕西 西安710000)

1 前言

文章开始之前,需要特殊说明一点,在其他编程语言中,也有元胞数组的概念,但是本文中所阐述的元胞数组,是基于MATLAB软件介绍的,它为 MATLAB中的一种数据类型[1],相关特性可能与其他软件有所不同。

软件开发过程中,我们有时需要一次传递多维数据到一个循环中,普通数据传递一次只能传递一个数据,但是使用元胞,我们可以一次传递多维数据。与结构体通过域名访问元素值不同,元胞数组通过索引方式访问包含在其中的元素值,正是由于元胞数组的这种特性,使得其与循环联合使用时,可以解决很多软件开发过程中遇到的问题。

2 元胞数组

2.1 元胞数组的定义

元胞数组由元胞组成,是一个能够存放任何数据类型、任意大小数组的数据容器。同一个元胞数组中各元胞的内容可以不同,可以是MATLAB或用户自定义的数据类型[2]。每个数据类型可以有任意维数。能够混合存储任意类型和大小的数组是元胞数组一个重要功能,另外一个经常使用元胞的方式是存储不同长度的字符串。像MATLAB中其他数组一样,元胞数组必须为矩形形状,也就是说元胞数组的任何一维的每行每列都必须相等。了解结构体的人可能知道,结构体和元胞数组设计和目的都很相似,都提供了一种存储不同大小和不同类型数据的方式,两者最大的区别在于结构体使用域名来访问存储在其中的数据,而元胞数组则使用数字索引,所以我们可以利用索引的方法,一次传递多维数据。

2.2 元胞数组操作

为方便理解本文中的相关例子,我们先来讲解一下元胞数组的一些基本操作。元胞数组的操作包括元胞数组创建、元胞数组连接、元胞数组索引、元胞数组赋值和从元胞数组返回值等内容[3],这里仅对元胞数组创建、赋值和索引等内容做简要介绍。

2.2.1 创建元胞数组

在MATLAB中创建元胞数组和创建其他类型数组类似,主要的区别是创建元胞数组时需要使用花括号将元胞数组的内容或索引括起来,而创建其他类型数组时使用的为中括号[4]。元胞数组中的每行元素用逗号或空格符做间隔,各列之间用分号做间隔。在赋值运算符“=”右边用花括号“{}”来为一个元胞数组赋值。例如使用命令A={B C D E}就可以创建一个包含B C D E不同数据类型的元胞数组,可以在一个元胞数组中嵌套另一个元胞数组。也可以使用函数cell来创建元胞数组,运行cell(m,n)命令就创建了一个大小为m×n的元胞数组。

2.2.2 元胞数组索引

当处理元胞数组时,你可以选择元胞数组中整个元胞来进行操作,也可以选择元胞中的内容进行操作,第一种方式是元胞索引,第二种方式是内容索引[5]。x=C(s)命令返回元胞数组C中下标为s的元胞,x=C{s}命令返回元胞数组C中下标为s的内容,假设一个元胞数组包含多个元胞,每个元胞又为包含一个或多个元素的数组,则x=C{s}(t)命令返回元胞数组中由下标s指定的元胞中的下标为t的数组元素。

在这里列举一个简单的例子来说明上述操作,首先在MATLAB软件中输入下面两条语句:

data(1,:)= {'张 三'49 {58 98.3 [103 72]}};

data(2,:)= {'李 四'25 {60 98.6 [105 75]}};

这两个语句创建了一个2×3的元胞数组data,其中每一行中又嵌套了一个元胞数组,嵌套的元胞数组中最后一个元素为一个向量。使用a=data(2,1)命令时,命令窗口返回a=’李四’;使用b=data{2,1}命令时,命令窗口返回b=李四;使用c=data{2,3}(1)命令时,命令窗口返回c=[60],使用d=data{2,3}{1}命令时,命令窗口返回d=60,各运算结果如图1所示。

使用whos命令来查看各个变量的类型,如图2所示,变量a、c和data的类型为元胞,变量b的类型为字符型,变量d的类型为数值型。

3 使用元胞传递数组数据实例

在使用MATLAB编程时,我们可能遇到这样的情况,需要将一个以上的数据同时传递到一个循环中。例如,在编程绘制矿区工作面示意图时,假设一个矿区有三个矩形工作面。

如果直接使用Plot命令绘图这三个工作面,那么三个工作面首尾则由一条直线连接在一起,如下图图3所示:

为了解决上述问题带来的不便,一种较理想的方法是使用一个循环每次绘制一个工作面。但是,这就需要一次传递给循环一个工作面的数据。使用其他类型数据传递给循环时,一次只能传递一个数据。由于元胞值可以为一个数组,每个元胞又可以整体看做一个数据,同时可以使用索引寻访每个元素值,所以我们可以在循环中一次传递多维数据,从而实现上述需求。编写MATLAB程序如下:

[filename,pathname]=uigetfile(...

{'*.txt';'*.xls';'*.xlsx';'*.xlsb';'*.xlsm';...

'*.*'},...

'坐标数据导入');

if isequal([filename,pathname],[0,0])

return

else

File=fullfile(pathname,filename);

end %读取工作面坐标文件

gzmzb=importdata(File);%导入工作面坐标数据到变量gzmzb中

x_gzm=gzmzb(:,1);%将变量gzmzb第一列数据赋值给x_gzm

y_gzm=gzmzb(:,2);%将变量gzmzb第二列数据赋值给y_gzm

k=length(x_gzm)/4;%根据坐标求工作面数目

gzm=cell(k,1);%创建和工作面数目相等的元胞数组

gzm(:)={zeros(5,2)};%对元胞数组中每个元胞初始化

jj=1;

for mm=1:length(x_gzm)

if mod(mm,4)==0

gzm{jj}(1,1)=x_gzm(mm-3);

gzm{jj}(2,1)=x_gzm(mm-2);

gzm{jj}(3,1)=x_gzm(mm-1);

gzm{jj}(4,1)=x_gzm(mm);

gzm{jj}(5,1)=x_gzm(mm-3);

gzm{jj}(1,2)=y_gzm(mm-3);

gzm{jj}(2,2)=y_gzm(mm-2);

gzm{jj}(3,2)=y_gzm(mm-1);

gzm{jj}(4,2)=y_gzm(mm);

gzm{jj}(5,2)=y_gzm(mm-3);

jj=jj+1;

end

end %将4个坐标组成一个工作面完整坐标,为了使工作面闭合,%添加第五个坐标,其值和第一个坐标相等

for nn=1:k

plot(gzm{nn}(:,1),gzm{nn}(:,2),'-r','linewidth',2.5);

hold on

end %绘制工作面示意图

程序中使用cell(k,1)命令创建了一个大小为k×1的元胞数组,然后使用gzm(:)={zeros(5,2)}命令,将元胞数组中每个元胞的值初始化为5×2的全零数组,这样做可以提高程序运行速度,并防止发生内存溢出错误,最后使用循环将工作面坐标赋值给每个元胞并绘图。运行该程序如图4所示:

4 结语

MATLAB不仅功能强,而且使用方便,易于掌握[6]。使用其他方式也可以实现同样效果,但是使用元胞数组传递多维数据更方便、高效、直观。元胞数组设计的目的就是为了存储不同类型、不同大小的数据,并通过索引来寻访其中的值,所以元胞数组和循环的联合使用,必定成为传递多维数据的一种理想方案。

猜你喜欢
数据类型元胞数组
基于元胞机技术的碎冰模型构建优化方法
JAVA稀疏矩阵算法
三维元胞自动机模拟微生物生长研究
JAVA玩转数学之二维数组排序
基于元胞自动机的网络负面舆论传播规律及引导策略研究
基于元胞自动机下的交通事故路段仿真
基于元胞自动机下的交通事故路段仿真
更高效用好 Excel的数组公式
基于SeisBase模型的地震勘探成果数据管理系统设计
线上众筹产品的特征分析与研究