找回密码
 注册
Simdroid-非首页
查看: 187|回复: 5

[讨论] 数组操作练习

[复制链接]
发表于 2013-5-9 11:23:30 | 显示全部楼层 |阅读模式 来自 河北廊坊
本帖最后由 qibbxxt 于 2013-5-9 15:01 编辑

在cody上面看见这样一个问题,希望大家讨论下:
Given an array (x) of integers, the "counting" array (y) is showing the number of identical consecutive integers in x in front of the integer itself. For example, if
  • x = 1
  • y = [1 1],
because there is one "1". If then
  • x = [1 1]
  • y = [2 1],
because there are now two "1"s. Finally, a more complex example:
  • x = [1 2 2 4 4 3 0 0 1]
  • y = [1 1 2 2 2 4 1 3 2 0 1 1].
So y gets two elements for each series of identical integers in x. (I hope this problem does not exist already)

来自于:http://www.mathworks.cn/matlabcentral/cody/problems/1290-a-different-counting-method
发表于 2013-5-11 01:00:14 | 显示全部楼层 来自 四川成都
Simdroid开发平台
抛砖引玉一下,供大家参考:

  1. <P>function y=next_series(x)
  2. if (isvector(x)~=1)                         %避开矩阵输入
  3.     error(message('What you input is Not a vector!'));
  4. else
  5.     n=length(x);
  6.     if (n==1)                               %当为标量时的处理办法
  7.         y=[1 x];
  8.     else
  9.         [h,l]=size(x);                      %当为向量时的处理办法        
  10.         if (h~=1)
  11.             xtemp=x';
  12.         else
  13.             xtemp=x;
  14.         end
  15.         a=[ones(1,n);xtemp];
  16.         [h,l]=size(a);
  17.         p=1;
  18.         for k=2:l
  19.             if a(2,k)==a(2,p)
  20.                 a(1,p)=a(1,p)+1;
  21.                 a(1,k)=0;
  22.             else
  23.                 p=k;
  24.             end
  25.         end
  26.         c=a(1,:);
  27.         d=nonzeros(c);
  28.         n=length(d);
  29.         m=1;
  30.         y=zeros(2,n);
  31.         for k=1:l
  32.             if a(1,k)~=0
  33.                 y(:,m)=a(:,k);
  34.                 m=m+1;
  35.             end
  36.         end
  37.         y=y(:)';
  38.     end
  39. end           </P>
  40. <P> </P>
复制代码

点评

格老子的,看了楼下两位的代码,突然感觉自己这砖有够厚!  发表于 2013-5-13 20:38

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-5-11 01:39:52 | 显示全部楼层 来自 英国
经典的run-length encoding问题:
  1. function y = next_series(x)
  2.   idx = find(diff([x,nan]));
  3.   y0 = [diff([0 idx]); x(idx)];
  4.   y = y0(:)';
  5. end
复制代码

点评

神作!赞一个  发表于 2013-5-11 17:09

评分

2

查看全部评分

回复 不支持

使用道具 举报

 楼主| 发表于 2013-5-11 20:02:42 | 显示全部楼层 来自 河北廊坊
感谢各位参与,下面我来大致列举一下cody上面的做法
1.利用regexprep的动态正则表达式功能来实现
  1. function ans = next_series(x)
  2. str2num(regexprep(char(x+48), '(\d)(\1*)', '${char(numel($2)+49)} $1 '));
  3. end
复制代码
这种做法的优点在于代码简洁,缺点在于当数字不是0-9之间是,该方面失效,\d只能是0-9,但是此方法有助于练习正则表达式的使用,因为cody上面一个变量的size为2,所以大家尽量减少变量和函数的使用,这个时候就出现了ans和str2num之类,核心还是regexprep函数的使用

2. 使用2次diff
  1. function ans = next_series(x)
  2. find(diff([x inf]));
  3. [diff([0 ans]); x(ans)];
  4. ans(:)';
  5. end
复制代码
diff函数在该类问题中有天然的优势,比如求解局部的极值等问题,改代码简洁高效,应用范围广,属于正解

3.  常规的做法
  1. function y = next_series(x)
  2. y=[];
  3.   while ~isempty(x)
  4.     val=find(x~=x(1),1);
  5.     if isempty(val)
  6.      val=length(x)+1;
  7.     end
  8. y=[y val-1 x(1)];
  9. x=x(val:end);
  10. end
复制代码
这个没有什么好说的,有很多不同的版本

4. 用了一次diff,用arrayfun函数操作的
  1. function y = next_series(x)
  2.   idx = find(diff(x));
  3.   y0 = cell2mat(arrayfun(@(a, b) [ b-a+1; x(a) ],[ 1 idx + 1 ],[ idx length(x) ], 'uni', 0));
  4.   y = y0(:)'
  5. end
复制代码
时间有限,先不分析,这个代码,大家可以去分析分析

再次感谢大家参与,下次我还会再提供这样的一些题目,希望大家继续支持

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-5-11 20:27:51 | 显示全部楼层 来自 新疆乌鲁木齐
建议大家去cody做做题,练上100个题目估计MATLAB的理解都会上两三个层次。前一段时间做了几个正则替换表达式构造的题目,感觉就很有提高。

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-5-12 01:09:11 | 显示全部楼层 来自 英国
qibbxxt 发表于 2013-5-11 20:02
感谢各位参与,下面我来大致列举一下cody上面的做法
1.利用regexprep的动态正则表达式功能来实现这种做法的 ...

arrayfun的那个好像是我提交的。。后来觉得还是太丑就用RLE做了一遍

点评

哦,不错的,希望继续加油,一起玩cody  发表于 2013-5-13 08:37
其实diff还好,容易想到,感觉inf和ans两个细节其实才更美妙。  发表于 2013-5-12 10:04
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-5-8 08:54 , Processed in 0.054382 second(s), 19 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表