- 积分
- 32
- 注册时间
- 2009-7-29
- 仿真币
-
- 最后登录
- 1970-1-1
|
发表于 2013-7-4 21:21:17
|
显示全部楼层
来自 英国
nwcwww 发表于 2013-6-20 10:31
把17和18楼的代码重新整理下吧。二者其实是一回事。我在这层写的详细些,方便还没入门的朋友。其他诸位在代 ...
原问题隔得太远了,直接引用一下:
Build a function with two input arguments: a string and a word length (number of letters),
that outputs a vector of counts of the 26 letters of the alphabet, specific to words with a given length.
各位的代码都是下例基础上验证的。
txt = 'Hello World, from MATLAB';
n1 = 5; % n后面跟的是数字1.
所以17楼的代码,如果我自己正常写多半如下:
a = regexp(lower(txt),'\<\w{5}\>','match');
b = strcat(a{:});
Count_all = arrayfun(@(x) length(regexp(b, char(96+x))), 1:26);
很欣赏上面的代码,它是arrayfun和regexp这两个Matlab中比较灵活的函数相结合的典范。
qibbxxt在23#提到accumarray函数并用accumarray编写代码,但稍显复杂。
accumarray(reshape(char(regexp(lower(txt),sprintf('\\<\\w{%d}\\>',nl),'match'))-'`',[],1),1,[26,1])'
这里就用accumarray函数的另一种形式改写一下。
- txt = 'Hello World, from MATLAB'; % 输入参数
- n1 = 5; % 输入参数
- pattern = ['\<\w{',num2str(n1),'}\>']; % 也可用sprintf()的形式,但前者在此处更直观一些。
- a = regexpi(txt,pattern,'match'); % 与上同,a = {'hello', 'world'},可以写成 a = regexp(lower(txt),pattern,'match')。
- <font color="#8b0000">% 不知道楼主们计算代码size的原则是什么,代码分开来写与并起来写的size应该算一样,且更应提倡。</font>
- b = strcat(a{:}); % 与上同,b =‘helloworld’,可以直接用 b = [a{:}];
- subs = arrayfun(@(x) regexpi(char(97:122),x),b);
- % 将匹配模式[a-z]和要查找的字符串b对调一下。返回b中的各位置字母在[a-z]匹配模式字母串中的位置。
- % 思路与qibbxxt一样。
- % subs =
- % 8 5 12 12 15 23 15 18 12 4
- Count_all = accumarray(subs',1,[26,1])' % 统计各个位置(对应于各个字母)出现的次数。
- % 写成综合的形式:
- % Count_all = accumarray(arrayfun(@(x) regexpi(char(97:122),x),b)',1,[26,1])' % 四个嵌套函数。
- % qibbxxt 用sprintf(...) 引入动态参数n1,使得代码中的函数嵌套层次变多了,复杂度变大了,可读性降低了。
- <font color="#8b0000">% 个人观点是:代码简洁要照顾到可读性,对于大多数人来说,一行代码三四个函数嵌套顶多了。</font>
- % 另,22# liuyalong008 的代码应该最简洁。
- txt = 'Hello World, from MATLAB'; % 输入参数
- n1 = 5; % 输入参数
- pattern = ['\<\w{',num2str(n1),'}\>']; % 或写为 sprintf('\\<\\w{d}\\>',nl) 的形式;
- a = regexpi(txt,pattern,'match');
- Count_all = histc([a{:}],97:122)
复制代码 |
评分
-
2
查看全部评分
-
|