matlab ele,Matlab迭代器模式

迭代器(Iterator)模式,又叫做游标(Cursor)模式。提供一种方法访问一个容器(container)或者聚集(Aggregator)对象中各个元素,而又不需暴露该对象的内部细节。在采用不同的方式迭代时,只需要替换相应Iterator类即可。本文采用Matlab语言实现对元胞数组和string数组的遍历。

Aggregator.m

classdef Aggregator < handle

methods(Abstract)

iterObj = createIterator(~);

end

end

CellAggregator.m

classdef CellAggregator < Aggregator

properties

cell

end

methods

function obj = CellAggregator(cell)

obj.cell = cell;

end

function iterObj = createIterator(obj)

iterObj = CellIterator(obj);

end

end

end

StringAggregator.m

classdef StringAggregator < Aggregator

properties

string_arr

end

methods

function obj = StringAggregator(string_arr)

obj.string_arr = string_arr;

end

function iterObj = createIterator(obj)

iterObj = StringIterator(obj);

end

end

end

Iterator.m

classdef Iterator < handle

methods(Abstract)

hasNext(~);

next(~);

end

end

CellIterator.m

classdef CellIterator < Iterator

properties

index = 1;

aggHandle;

end

methods

function obj = CellIterator(agg)

obj.aggHandle = agg;

end

function res = hasNext(obj)

if(obj.index <= length(obj.aggHandle.cell))

res = true;

else

res = false;

end

end

function ele = next(obj)

if(obj.hasNext())

ele = obj.aggHandle.cell{obj.index};

obj.index = obj.index + 1;

else

ele = [];

end

end

end

end

StringIterator.m

classdef StringIterator < Iterator

properties

index = 1;

aggHandle;

end

methods

function obj = StringIterator(agg)

obj.aggHandle = agg;

end

function res = hasNext(obj)

if(obj.index <= obj.aggHandle.string_arr.length)

res = true;

else

res = false;

end

end

function ele = next(obj)

if(obj.hasNext())

ele = obj.aggHandle.string_arr(obj.index);

obj.index = obj.index + 1;

else

ele = string.empty();

end

end

end

end

测试代码:

cell = CellAggregator({'matlab','cell','iter'});

iterObj = cell.createIterator();

while iterObj.hasNext()

disp(iterObj.next());

end

str_arr = StringAggregator(["matlab","string","iter"]);

iterObj = str_arr.createIterator();

while iterObj.hasNext()

disp(iterObj.next());

end

迭代器模式不仅可以对集合进行顺序遍历,而且可以以用户想要的条件进行遍历,如果想要统计列表中所有偶数的和,可以写成循环语句,如下所示:

test_for.m

list = [13,8,17,11,8,19,18,12,13,12];

sum = 0;

for i=1:length(list)

if mod(list(i),2) == 0

sum = sum + list(i);

end

end

disp("列表中所有偶数的和:" + sum);

sum = 0;

for i=1:length(list)

if mod(list(i),2) == 1

sum = sum + list(i);

end

end

disp("列表中所有奇数的和:" + sum);

如果要统计列表中所有奇数的和,这就需要对循环语句块进行修改,如上所示。这就违反了对修改关闭的原则。而迭代器模式可以将循环语句块和业务语句块(sum求和)分离出去,这就需要对Aggregator和Iterator类进行继承,如下所示:

ListAggregator.m

classdef ListAggregator < Aggregator

properties(Constant)

EVEN_ITER = 0

ODD_ITER = 1

end

properties

list

end

methods

function obj = ListAggregator(list)

obj.list = list;

end

function iterObj = createIterator(obj,type_iter)

if(type_iter == ListAggregator.EVEN_ITER)

iterObj = EvenIterator(obj);

else

iterObj = OddIterator(obj);

end

end

end

end

OddIterator.m

classdef OddIterator < Iterator

properties

index = 1;

aggHandle;

end

methods

function obj = OddIterator(agg)

obj.aggHandle = agg;

end

function res = hasNext(obj)

res = false;

while(obj.index <= length(obj.aggHandle.list))

if mod(obj.aggHandle.list(obj.index),2) == 1

res = true;

break;

end

obj.index = obj.index + 1;

end

end

function ele = next(obj)

if(obj.hasNext())

ele = obj.aggHandle.list(obj.index);

obj.index = obj.index + 1;

else

ele = [];

end

end

end

end

EvenIterator.m

classdef EvenIterator < Iterator

properties

index = 1;

aggHandle;

end

methods

function obj = EvenIterator(agg)

obj.aggHandle = agg;

end

function res = hasNext(obj)

res = false;

while(obj.index <= length(obj.aggHandle.list))

if mod(obj.aggHandle.list(obj.index),2) == 0

res = true;

break;

end

obj.index = obj.index + 1;

end

end

function ele = next(obj)

if(obj.hasNext())

ele = obj.aggHandle.list(obj.index);

obj.index = obj.index + 1;

else

ele = [];

end

end

end

end

test_iter.m

list_agg = ListAggregator([13,8,17,11,8,19,18,12,13,12]);

iterObj = list_agg.createIterator(ListAggregator.EVEN_ITER);

sum = 0;

while iterObj.hasNext()

sum = sum + iterObj.next();

end

disp("列表中所有偶数的和:" + sum);

iterObj = list_agg.createIterator(ListAggregator.ODD_ITER);

sum = 0;

while iterObj.hasNext()

sum = sum + iterObj.next();

end

disp("列表中所有奇数的和:" + sum);

如果需要返回列表标,可以将next函数的返回值定义成[ele,index] = next(obj),python里面有yield关键字,可以让迭代器模式更加简洁,见参考资料。

迭代器模式还可以扁平化多层嵌套循环,如果找到所有水仙花数,可以使用三层循环,代码如下:

test_for.m

a = 1:9;

b = 0:9;

c = 0:9;

for i=1:length(a)

for j = 1:length(b)

for k = 1:length(c)

num = a(i)*100 + b(j)*10 + c(k);

if a(i)^3 + b(j)^3 + c(k)^3 == a(i)*100 + b(j)*10 + c(k)

disp("" + num + "是水仙花数");

end

end

end

end

如果使用迭代器模式来简化三层循环,只需要对Aggregator和Iterator类进行继承,代码如下:

MutiListAggregator.m

classdef MutiListAggregator < Aggregator

properties

lists

end

methods

function obj = MutiListAggregator(varargin)

obj.lists = varargin;

end

function iterObj = createIterator(obj)

iterObj = MutiListIterator(obj);

end

end

end

MutiListIterator.m

classdef MutiListIterator < Iterator

properties

indexs = [];

lengths = [];

aggHandle;

end

methods

function obj = MutiListIterator(agg)

obj.aggHandle = agg;

for i= 1:length(obj.aggHandle.lists)

obj.lengths(i) = length(obj.aggHandle.lists{i});

end

obj.indexs = ones(1,length(obj.aggHandle.lists));

end

function res = hasNext(obj)

if(obj.indexs(1) > obj.lengths(1))

res = false;

else

res = true;

end

end

function varargout = next(obj)

if(obj.hasNext())

for i = 1:length(obj.aggHandle.lists)

temp_list = obj.aggHandle.lists{i};

varargout{i} = temp_list(obj.indexs(i));

end

obj.indexs(length(obj.aggHandle.lists)) = obj.indexs(length(obj.aggHandle.lists)) + 1;

for i = length(obj.aggHandle.lists):-1:2

if(obj.indexs(i) > obj.lengths(i))

obj.indexs(i) = mod(obj.indexs(i), obj.lengths(i));

obj.indexs(i - 1) = obj.indexs(i - 1) + 1;

end

end

else

for i = 1:length(obj.aggHandle.lists)

varargout{i} = [];

end

end

end

end

end

test_iter.m

list_agg = MutiListAggregator(1:9,0:9,0:9);

iterObj = list_agg.createIterator();

while iterObj.hasNext()

[a,b,c] = iterObj.next();

num = a * 100 + b * 10 + c;

if a^3 + b^3 + c^3 == a * 100 + b * 10 + c

disp("" + num + "是水仙花数");

end

end

参考资料:

https://mp.weixin.qq.com/s/tghaVkTPUijBJO0qxSXdZQ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值