MATLAB映射表数据结构
基本介绍
映射表数据结构是什么,我就不多说了。之前在Python和CPP中用的比较多。结果今天恰好收到老板的一个小任务。帮忙写个简单的matlab
程序。简单是真的很简单。要求如下
但是,在分析问题的过程中,发现了一个问题。根据投掷的骰子数量、次数的不同,其可能的平均值也会出现不同的差异。并且可能会出现相同的组合情况,如1,2,1和2,1,2。
那么,我们的需求就变成了,如何去寻找一个容器,能够来存储这样的数据,并且支持动态扩充呢?在cpp里面,肯定就是map
了撒。
在此之前,matlab并没有用到
containers
这部分的数据结构。今天第一次接触到。所以想记录一下使用心得。
MATLAB中的map容器
既然我们知道了matlab也提供有这么方便的容器,那么我们可以通过help containers.Map
来寻找他的正确打开方式
点击containers.Map
我们可以发现,我们可以通过四种方式定义我们的对象。
M = containers.Map(keySet,valueSet) % 拷贝构造?
M = containers.Map(keySet,valueSet,
'UniformValues',isUniform) % 重载拷贝构造,多的参数为'UniformValues'
M = containers.Map('KeyType',kType,'ValueType',vType)
M = containers.Map
这里我用到的其实是第三种。也类似于c++中的map<keyT, valueT> mp
然后在matlab中支持定义多种数据类型的键值类型
在完成容器的定义后,我们可以做如下一系列操作
map容器的属性及对象函数
对于创建好的containers.Map
对象,我们可以通过得到他的相关属性
%代码测试
testMap = containers.Map('keyType','double', 'ValueType','int32');
testMap.Count; //计算键值对组数量
testMap.KeyType; //键的数据类型
testMap.ValueType; //值的数据类型
对象函数
对象函数其实学过cpp或者python的都能够很直观地明白他的作用。只是在得到这些数据的时候,如何进行操作的问题。
因此,我想结合开头的那个小任务,将他的对象函数中的isKey、keys、values
的实际使用演示一下
开头的问题解决
function rolls(times, nums, sides)
% 传入参数为:
% 1. sides:骰子的面数,默认为6
% 2. times:投掷的次数默认为1000
% 3. nums:同时投掷的骰子个数,默认为1
if(nargin < 3)
sides = 6;
else
if(nargin < 2)
nums = 1;
else
if (nargin == 0)
times = 1000;
end
end
end
%初始化一个平均值组合
avgMap = containers.Map('keyType','double', 'ValueType','int32');
for i = 1:times
avg = sum(randi(sides,nums,1))/nums;
if(isKey(avgMap, avg))
avgMap(avg) = avgMap(avg)+1;
else
avgMap(avg) = 1;
end
end%统计投掷结果
%可视化工作
%统计直方图
num_of_avg_types = avgMap.Count; %计算平均值的组合情况
valueSet = values(avgMap);
keySet = keys(avgMap);
avg_vector = zeros(num_of_avg_types,1);
for i = 1: num_of_avg_types
avg_vector(i) = valueSet{i};
end
bar(avg_vector);
titlename = ['同时投掷',num2str(nums),'枚',num2str(sides),'面骰子',num2str(times),'次平均数统计直方图'];
title(titlename);
xticks(1:num_of_avg_types);
xticklabels(keySet);
xtickangle(75);
xlabel('平均值')
ylabel('出现次数')
grid on
saveas(gcf,titlename,'jpg');
% close; %默认图像保存后不关闭
%变换曲线图
end
所贴代码为完整的实现代码,需要注意的是,我们keys
返回的是一系列cell
,我们恰好可以用它来作为x轴的刻度标签xticklabels(keySet);
。
但是values需要单独提出来(这里不知道是否有更好的办法)