[心得] 自我描述数列与String pattern

楼主: jurian0101 (Hysterisis)   2013-03-27 23:19:28
自我描述数列是这玩意儿
http://zh.wikipedia.org/wiki/%E5%A4%96%E8%A7%80%E6%95%B8%E5%88%97
= 1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211 (说明见上)
[实作1]
LookSay[str_String] := StringJoin @@
StringCases[str, p : ((x_(*?DigitQ*)) .. ~~ (x_ | "")) :>
ToString@StringLength[p] <> StringTake[p, {1}]];
- -
NestList[LookSay, "1", 10]
=> {"1", "11", "21", "1211", "111221", "312211", "13112221",
"1113213211", "31131211131221", "13211311123113112211",
"11131221133112132113212221"}
- -
说明: 函数核心部分在于
StringCases[str, ((x_(*?DigitQ*)) .. ~~ (x_ | ""))]
它的作用是把 "11223aaaab" 拆成 {"11", "22", "3", "aaaa", "b"}
若把(*?DigitQ*)的注解拿掉,则忽略掉字母。
叫做核心因为string pattern我最不熟,这部分改了最久XD
其他部分只是在做 "111" -> "3个1" -> "31" 这件事而已,是个拼拼凑凑。
- * - *
ListPlot[Log[StringLength /@ NestList[LookSay, "1", 40]],
PlotLabel -> "Log[length[LS[n]]]"]
(*数列的长度依指数增长的图示,原理的说明见wiki跟下*)
http://www.njohnston.ca/2010/10/a-derivation-of-conways-degree-71-look-and-say-polynomial/
楼主: jurian0101 (Hysterisis)   2013-03-27 23:33:00
哭哭,比OEIS A005150给的代码慢三倍。
作者: sunev (Veritas)   2013-03-28 00:05:00
为什么要用String?f[n_Integer /; n > 0] := FromDigits@Flatten@({Length[#], First[#1]} & /@ Split@IntegerDigits@n)如果把最前面和最后面的FromDigits和IntegerDigits拿掉可以再快一点。
楼主: jurian0101 (Hysterisis)   2013-03-28 00:12:00
因为string pattern这块一直不敢碰它,这次当作练习效率的话OEIS A005150底下给的程式码看来落落长却莫名地快,我/你/他的代码跑第50个数,需时约3:2:1又我不太会监测Memory usage,不知哪个较省
作者: sunev (Veritas)   2013-03-28 00:28:00
突然发现我的f和他的第二个写法一模一样。但是如果把FromDigits和IntegerDigits拿掉就比第一个快了。g[n_] := Flatten[({Length[#1], First[#1]} &) /@ Split[n]NestList[g, {1}, 50]; // Timing
楼主: jurian0101 (Hysterisis)   2013-03-28 00:50:00
XD 现在你的写法跟Steven Wolfram一模一样,在说明文件Split精巧范例的第二个,同时也在NKS 905页上
作者: sunev (Veritas)   2013-03-28 02:06:00
XD

Links booklink

Contact Us: admin [ a t ] ucptt.com