碎碎念

2007, August 27

用SED打印斐波那契序列

Filed under: sed

整理邮件时看到了这个SED脚本(2006年1月),好像是我写的最后一篇关于SED的文章……

# 脚本开始
# SED打印斐波那契序列

# 调用:seq 10 | sed -f fib.sed # 打印前10个数字(运行较慢,不要打印太多)
# yes | sed -f fib.sed # 打印序列直到溢出

# 这个脚本用模拟的方式进行数字运算。有关这种方法的更
# 多细节可以参考Greg Ubben写的教程:
# http://sed.sourceforge.net/grabbag/tutorials/

1{
# 下面字母串的长度决定了可打印的序列长度
# 可以修改下面的字串使之支持更多的序列
# s/.*/zyxwvutsrqponmlkjihgfedcba/
s/.*/kjihgfedcba/
# 初始化序列为“1, 1”
s/.*/ &a &a /; h; d
}

# 从hs取最后两组数字串进行运算
g
s/.* \(.*\) \(.*\) $/\1\2/

# 进行进位操作前先对两组数字加总(其实是排序)
s/\(\(.\)\2*\)/\1 /g
:lpsort
s/\(\([^ ]\)\2\{0,\}\)\( .*\)\2/\1\2\3/
tlpsort
s/ //g

# 调整加总的结果
# 加总时我们进行如下运算:
# edcbaa + edcbaaa = edcbaaaa
# 1 + 2 = 3
# 但实际在加总(排序)后我们等到的结果是:
# edcbaa + edcbaaa = eeddccbbaaaaa
# 我们需要将eeddccbbaaaaa转换为edcbaaaa

s/\(.\)\(\1\{1,19\}\)/\2/g

# 进行进位操作。
# baaaaaaaaaaa进位后成为bba——10

:doCarry
s/\(.\)\(\(.\)\3\{9\}\)\3/\1\1\3/
t doCarry

# 简单(粗糙)的溢出检验
# 因为第一个字母如果超过9个说明没有正常进位——即溢出
/^\(.\)\1\{9\}/{g;s/$/ ++OVERFLOW++/; b2digi}

# 将这一轮的结果保存到hold space。记得在最后加上一个空格。
G
s/\(.*\)\n\(.*\)/\2\1 /
$!{h;d}
g

# 运算完后将模拟结果转为数字表示的结果
:2digi
s/\([a-z]\)\1\{9\}/9/g
s/\([a-z]\)\1\{8\}/8/g
s/\([a-z]\)\1\{7\}/7/g
s/\([a-z]\)\1\{6\}/6/g
s/\([a-z]\)\1\{5\}/5/g
s/\([a-z]\)\1\{4\}/4/g
s/\([a-z]\)\1\{3\}/3/g
s/\([a-z]\)\1\1/2/g
s/\([a-z]\)\1/1/g
s/\([a-z]\)/0/g
s/ 0*/ /g
# 溢出检验需要q命令
q
# 脚本结束

Comments »

The URI to TrackBack this entry is: http://blah.blogsome.com/2007/08/27/sed_fibonacci/trackback/

No comments yet.

RSS feed for comments on this post.

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>



请输入验证码。

Get free blog up and running in minutes with Blogsome
Theme designed by Jay of onefinejay.com