找回密码
 注册
Simdroid-非首页
楼主: qibbxxt

【讨论】正则系列

[复制链接]
 楼主| 发表于 2013-7-6 09:45:58 | 显示全部楼层 来自 河北廊坊
补一个第9题的
  1. sum(str2num(regexprep(str,'[^0-9]',blanks(1))))
复制代码
思路:
将非0-9的字符替换为空格
然后用str2num转化为数组
再用sum函数求和

点评

那我把你这个代码放在阿方索大神的leading前面做个宋兵甲铺垫铺垫,你货不能有意见啊,呵呵。  发表于 2013-7-6 22:04
回复 不支持

使用道具 举报

发表于 2013-7-6 11:01:33 | 显示全部楼层 来自 北京
Simdroid开发平台
bainhome 发表于 2013-7-4 01:45
给定的text文本中,把数字提取出来并求和。cody原链请参看:Problem 57. Summing Digits within Text
题目 ...

我也回答一个第九题的:
   另辟蹊径很有难度啊
我的和qi版类似:
  1. str(~ismember(str,[32 48:57]))=32
  2. sum(str2num(str))
复制代码
不过我的更繁琐
首先把除了空格和数字以外的字符全部转化为空格
再利用转换和求和即可

但是要补充一点的是小数是否也要考虑
那样的话就可以改成:
  1. str(~ismember(str,[32 46 48:57]))=32
  2. sum(str2num(str))
复制代码
  1. str='.2 4 6 8 who do we appreciate?'
  2. >> str(~ismember(str,[32 46 48:57]))=32
  3. sum(str2num(str))

  4. str =

  5. .2 4 6 8                     


  6. ans =

  7.                       18.2
复制代码

点评

更新至第9题,另外把你前面那个复杂字符串的look around编辑了,真比写代码麻烦多了。你看看有无错误或疏漏之处。  发表于 2013-7-6 23:37
一大早起来看到众位高手的帖子,感慨一下,周六上午不虚度啊,先仔细品味帖子  发表于 2013-7-6 11:53
所以说越往后写解法的水平越high,不能单纯以代码本身质量论英雄。现在simwe写个众人均赞誉的答案真心是个很有挑战性的活...  发表于 2013-7-6 11:06
回复 不支持

使用道具 举报

发表于 2013-7-6 12:31:37 | 显示全部楼层 来自 北京
bainhome 发表于 2013-7-5 20:18
cody原链接参看这里。
剔除且只剔除字符串首尾的多余空格(不包括其他符号)
题目原文:测试算例1:测试算例2 ...

第五题果然阴险:
主要是 \s-->Any white-space character; equivalent to   [ \f\n\r\t\v]
所以必须要吧\t给剔除掉
  1. regexprep(a,'^(?=[^\t])\s+|\s+$','')
复制代码
^(?=[^\t])\s+ 表示把除了\t以外的白色字符,^表示每行的开头
当然此pattern只限于开头是制表符,如果结尾也要限制就另说了

点评

如结尾也有限制,regexprep2次估计可以。如果单纯限定在剔除\t而不是其他思路,不知道有没有更好的办法。  发表于 2013-7-7 10:26
回复 不支持

使用道具 举报

发表于 2013-7-6 16:49:26 | 显示全部楼层 来自 英国
综合及优化一下第9楼的答案。
str = '4 and 20 blackbirds baked in a pie';

sum(str2double(regexp(str,'\d+','match')))  % \d+ 可以不用在两边加圆括号。另外时若将str2double换成str2num就不行,二者在用法上还是有些区别的。
str2num(regexprep(str,'\D+','+0')) % 将非数字字符变为+0,整个字符串变成了加法表达式,省去了显式求和步骤了,构思巧妙。这里用\D代替[^\d],更为直接。


sum(eval(sprintf('[%s]',regexprep(str,'\D+',' ')))) % 用sprintf构造成行向量的形式在求和。
sum(str2num(regexprep(str,'\D+',' ')))              % 用str2num化成行向量的形式;\D要比[^0-9]更直接,速度更快。

str(~ismember(str,[32 48:57]))=32;                  % 在ASCII字符集合中找出数字0-9,另辟蹊径,但ismember函数涉及到集合,运算耗时。
sum(str2num(str))

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-7-6 16:54:34 | 显示全部楼层 来自 英国
本帖最后由 lin2009 于 2013-7-6 18:19 编辑

第10题:
关键在用构造合适的匹配模式,仅删除字符串前后的(半角)空格(ASCII 32)。
pat = '^ *([^ ].*[^ ]) *$';  % 原字符串前后可能为半角空格。剩余部分的特征是前后都不是空格字符。
c = regexprep(a,pat,'$1');
assert(isequal(b,c))
验证:
  1. pat = '^ *([^ ].*[^ ]) *;

  2. %% 1
  3. a = 'no extra spaces';
  4. b = 'no extra spaces';
  5. c = regexprep(a,pat,'$1');
  6. assert(isequal(b,c))

  7. %% 2
  8. a = '      lots of space in front';
  9. b = 'lots of space in front';
  10. c = regexprep(a,pat,'$1');
  11. assert(isequal(b,c))

  12. %% 3
  13. a = 'lots of space in back      ';
  14. b = 'lots of space in back';
  15. c = regexprep(a,pat,'$1');
  16. assert(isequal(b,c))

  17. %% 4
  18. a = '      space on both sides    ';
  19. b = 'space on both sides';
  20. c = regexprep(a,pat,'$1');
  21. assert(isequal(b,c))

  22. %% 5
  23. a = sprintf('\ttab in front, space at end    ');
  24. b = sprintf('\ttab in front, space at end');
  25. c = regexprep(a,pat,'$1');
  26. assert(isequal(b,c))
复制代码

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-7-7 11:11:12 | 显示全部楼层 来自 北京
本帖最后由 liuyalong008 于 2013-7-7 11:39 编辑
bainhome 发表于 2013-7-5 20:18
cody原链接参看这里。
剔除且只剔除字符串首尾的多余空格(不包括其他符号)
题目原文:测试算例1:测试算例2 ...

突然觉得这个测试算例其实也是有bug的
不信试试这个:
  1. regexprep(a,'\s{2,}','')
  2. a( cumsum(deblank(a)-32 )~=0)
  3. deblank(strjust(a,'left'))
复制代码
应该增加以下算例:
  1. a = sprintf('\ttab in front, space at end\t    ')
复制代码
当然即使这样的算例,lin兄的代码也安然无恙
:lol

点评

贴了三个转空子的solution,但是里面的cumsum和strjust我还是比较喜欢的,尤其cumsum  发表于 2013-7-7 11:51
哈哈!娱乐至上。你得小心,祁彬彬这货最恨钻空子,他看到又要小宇宙爆发了  发表于 2013-7-7 11:20
回复 不支持

使用道具 举报

发表于 2013-7-7 11:22:10 | 显示全部楼层 来自 新疆乌鲁木齐
本帖最后由 liuyalong008 于 2013-7-7 13:27 编辑

我是用两个regexprep算的,这样正则判断部分的代价稍小一些。
  1. regexprep(regexprep(a,'^ *',''),' *$','')
复制代码
此题如不限定tab制表符不算空格,也可以用high level的strtrim命令——一个专门用来去首尾空格的函数。
ps:怎么我的代码里结尾标识的美元符号无法编辑,总是出现很多个?邪门,应该只有一个的,说明一下

点评

编辑模式真让人蛋疼,老是出错啊  发表于 2013-7-7 11:46
回复 不支持

使用道具 举报

发表于 2013-7-7 12:06:40 | 显示全部楼层 来自 新疆乌鲁木齐
本帖最后由 liuyalong008 于 2013-7-7 13:26 编辑

非贪婪搜索勉强应该也算个思路:
  1. regexprep(a,'^ *(.*?) *$','$1')
复制代码
不过我没有完全测试所有算例,写笔记写得头昏脑涨,我就不测了,假定它成功吧,呵呵...
ps:又是一堆美元符号,真心是讨厌!
用TeX语法写一个,可是"^"又是错的,用了转义字符也不行。干脆各位前半部分见代码、后半部分见TeX公式表达式吧:

点评

精彩!完全通过验证,马兄不会是会计出身吧,按$符号手都抽了  发表于 2013-7-7 12:13
回复 不支持

使用道具 举报

发表于 2013-7-7 12:19:34 | 显示全部楼层 来自 北京
bainhome 发表于 2013-7-5 20:18
cody原链接参看这里。
剔除且只剔除字符串首尾的多余空格(不包括其他符号)
题目原文:测试算例1:测试算例2 ...

再来一个非正则的,看别人的,觉得思路很好
strrep(strtrim(strrep(a,9,1000)),1000,9)
把制表符用一个较大的ascii来代替,然后用strtrim来去掉两端的白色字符
然后再替换回来

PS: deblank是去掉结尾的白色字符
        strtrim是去掉两端的
        要去掉前段的就strjust配合一下

点评

第10题已经在43楼附件中做了更新,后面就等着你们继续讨论,我的任务正式完成。  发表于 2013-7-7 14:33
回复 不支持

使用道具 举报

发表于 2013-7-7 17:52:54 | 显示全部楼层 来自 英国
我的解和lin兄的一样。

严格来讲,这题并不只是排除\t。原题要求的是处理ascii中的32, 故而\t \n \v \f \r都是无关的。所以用[^ ]应该是最好的办法。

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2013-7-8 10:26:23 | 显示全部楼层 来自 新疆乌鲁木齐
嗯.实际采用“' '”这种形式都差不多.毕竟test suite只给了\t一种,严格修整liu老弟的代码变成:
  1. function ans = removeSpaces(a)
  2. regexprep(regexprep(a,'^(?=[^\t\f\n\r\v])\s*',''),'(?=[^\t\f\n\r\v])\s*$','');
  3. end
复制代码
估计可以,没测试全部,随意改test5测了一下:
  1. a = sprintf('\f\n\vtab in front, space and tab both at end\r    ')
  2. a =

  3. tab in front, space and tab both at end
  4.    
  5. >> removeSpaces(a)
  6. ans =

  7. tab in front, space and tab both at end
复制代码

点评

效率肯定惨不忍睹,不过出题目的是多解扩展思路,这点自己就不想深究了,呵呵。  发表于 2013-7-8 10:28
回复 不支持

使用道具 举报

发表于 2013-7-22 18:17:29 | 显示全部楼层 来自 英国

题目11:倒读隐语

把每个单词的第一个字母移至末尾,并在其后加上字母ay。
原题链接见:Problem 1721. Backslang, odds are you used it at some point in time...

题目原文:
  1. Hatstay tiay! Onay oremay onay esslay. Ellway erehay reaay omesay xampleseay:

  2. str = 'The sky is falling, the sky is falling, or is it?'

  3. output = Hetay kysay siay allingfay, hetay kysay siay allingfay, roay siay tiay?

  4. Ustjay aay otenay, omesay unctuationpay ndaay apitalscay oday ountcay.

  5. Oodgay Ucklay!
复制代码
测试题目:


  1. %%
  2. str = 'The sky is falling, the sky is falling, or is it?'
  3. output = 'Hetay kysay siay allingfay, hetay kysay siay allingfay, roay siay tiay?'
  4. assert(isequal(backslang(str),output))

复制代码
  1. %%
  2. str = 'If Allen is Janes husband and Tom is Jill husband, who is Roys wife?'
  3. output = 'Fiay Llenaay siay Anesjay usbandhay ndaay Omtay siay Illjay usbandhay, howay siay Oysray ifeway?'
  4. assert(isequal(backslang(str),output))
复制代码
  1. %%
  2. str = 'This is the sentence I will use.'
  3. output = 'Histay siay hetay entencesay Iay illway seuay.'
  4. assert(isequal(backslang(str),output))
复制代码
  1. %%
  2. str = 'Christopher Columbus sailed the ocean blue!'
  3. output = 'Hristophercay Olumbuscay ailedsay hetay ceanoay luebay!'
  4. assert(isequal(backslang(str),output))
复制代码
回复 不支持

使用道具 举报

发表于 2013-7-23 08:25:48 | 显示全部楼层 来自 北京
nwcwww 发表于 2013-7-22 18:17
把每个单词的第一个字母移至末尾,并在其后加上字母ay。
原题链接见:Problem 1721. Backslang, odds are y ...

我先贴一个:
  1. regexprep(str,{'(?<=[A-Z])(\w)','(\<\w)(\w+\>)','(\<[A-Z]\>)'},...
  2.       {'${upper($1)}','$2${lower($1)}ay','$1ay'})
复制代码
首先把首字母是大写的单词中的第二个字符转成大写
其次把token 1和token 2调换位置,并加上ay
最后再把单个字符大写的保留并加上ay
个人觉得写得还是挺啰嗦的

评分

1

查看全部评分

回复 不支持

使用道具 举报

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

本版积分规则

Simapps系列直播

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

GMT+8, 2024-9-22 11:36 , Processed in 0.064957 second(s), 22 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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