庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

群里收到的消息,过去从来不转发这样的消息,可这条消息我必须得占用大家一点时间,也许能帮上忙。

有人求救(代转)

为什么现在电视上不播报江油地震受损失的情况,我老婆现在7个月的身孕,没有食物和水,,今天上午联系了一次,已经饿的不行了。。。
    急需求救。。。现在也没有救援队伍去江油,,电视上一次江油的灾情也没有报,,
    我也是军人,我们部队现在待命准备去四川汶川救灾,我愿意贡献自己全部的力量去救灾区的老乡。。。
    可是我老婆确没有人救。。。。我马上就要出发了,也许很难联系她,,,,虽然无论怎样我会尽全力去抢汶川救灾区老乡,,,可是希望在江油的老乡也能跟她带点吃的,哪怕一瓶矿泉水也行,,,求求老乡了,,,她现在在马路湾中国电信的门口公路上的一辆货车上。。。叫王琢,,是老师,,求各位老乡帮忙,,,
一个去汶川救灾的军人的恳求
知道江油肯定没有人能见到这个帖子,希望在外的人们能联系上江油的同胞们帮
帮忙发下,谢谢了就1分钟

posted @ 2008-05-14 22:13 dennis 阅读(1528) | 评论 (5)编辑 收藏

    本节主要讲述无穷流。
3.53,显然
(define s (cons-stream 1 (add-stream s s)))
定义是2的n次方组成的无穷数列,2,4,8,16,32...

3.54,定义阶乘组成的无穷序列:
(define (mul-streams s1 s2)
  (stream
-map * s1 s2))
(define factorials (cons
-stream 1 (mul-streams factorials (stream-cdr integers))))

3.55解答,比较有趣,也是不难的题目,列出来找出规律就成了,就是将(stream-car s)加到生成的序列中的每个元素上,通过stream-map,最后的结果就是每个元素都是前n个元素累积的结果,我的解答:
(define (partial-sums s)
  (cons
-stream (stream-car s) (stream-map (lambda(x) (+ x (stream-car s))) (partial-sums (stream-cdr s)))))

3.56,有了merge就好办了,根据条件合并起3种情况来就好:
(define S (cons-stream 1 (merge (scale-stream s 2) (merge (scale-stream s 3) (scale-stream s 5)))))

3.57,略过

3.58,观察到,num每次都与radix相乘并且radix保持不变,那么radix可以认为是一个基数,den也保持不变作为除数,那么这个序列就是以radix为基数对den求整数商的序列,不明白num为什么每次要变换成余数?这个序列有啥特别的用途呢?未解。
(expand 1 7 10)
=> 1 4 2 8 5 7 1 4 2 8

(expand 3 8 10)
=> 3 7 5 0 0 0 0 0 0 0
3.59解答:
a)只要将序列通过前面定义的mul-streams与整数的倒数序列相乘:
(define (integrate-series s)
  (mul
-streams (stream-map (lambda(x) (/ 1 x)) integers) s))

b)照着定义来了,cons的级数注意使用scale-stream乘以-1:
(define sine-series
  (cons
-stream 0 (integrate-series cosine-series)))

(define cosine
-series
  (cons
-stream 1
    (scale
-stream
      (integrate
-series sine-series)
      
-1)))

3.64解答:
(define (stream-limit s tolerance)
  (define (stream
-limit-iter stream current)
    (cond ((
or (stream-null? stream) (null? (stream-car stream))) #f)
          (else
           (let ((next (stream
-car stream)))
             (
if (< (abs (- next current)) tolerance)
                   next
                  (stream
-limit-iter (stream-cdr stream) next))))))
  (stream
-limit-iter (stream-cdr s) (stream-car s)))

习题3.65:
(define (ln-summands n)
  (cons
-stream (/ 1.0 n)
               (stream
-map - (ln-summands (+ n 1)))))
(define ln
-stream (partial-sums (ln-summands 1)))
(define ln
-stream2 (euler-transform ln-stream))
(define ln
-stream3 (accelerated-sequence euler-transform ln-stream))
经过欧拉变换加速过的级数收敛的很快,测测就知道

posted @ 2008-05-13 23:52 dennis 阅读(483) | 评论 (0)编辑 收藏

    在云风的blog上看到,已经有人做了完整的翻译。在这里下载。那天arbow还在问我,最后两部分怎么不翻了,今天晚上看见这blog才又想起这么回事,看了下过去的翻译,原来也翻到第7部分虚拟机咯,不过既然已经有了不错的中文版了,就不献丑了。我的兴趣转移的太快,前两周还在读cindy、mina源码,研究nio,现在又对AOP产生了兴趣,特意学了caesarj语言,这东西对习惯了Ruby的我,实在是有点郁闷;在目前的jvm指令架构里,折腾open class、mixin,还是不那么自然,不过作为AspectJ的扩展,还是有学习的价值的。自己有过想法,每年学一门新语言,caesarj算不上,那么python如何?其实我在学在用咯。不过python没有带来更大的惊喜,python中规中矩,感觉类似动态语言中的java,没有像刚接触scheme带来的眼前一亮,而我是需要新鲜感的人,也许传说中的很难理解的haskell是我的下一个学习对象。

posted @ 2008-05-09 23:44 dennis 阅读(568) | 评论 (0)编辑 收藏

    流是通过延时求值实现的,Ruby中实现stream也是可以做到,可惜就是没有尾递归优化。按照sicp,首要的是两个函数:delay和force:
def mem_proc(exp)
  alread_run
=false
  result
=false
  
lambda{
    
if !alread_run
      result
=exp.call
      alread_run
=true
      result
    
else
      result
    end
  }
end
def force(delayed_object)
  delayed_object.call
end
def delay(exp)
  mem_proc(
lambda{exp})
end
    delay函数返回延时对象,就是对于未来某个时间求值表达式的承诺;force函数以延时对象为参数,进行相应的求值工作,这里的mem_proc用于记忆已经求值过的表达式。定义stream的constructor和selector函数:
def cons_stream(a,b)
  
return a,delay(b)
end
def stream_car(s)
  s[0]
end
def stream_cdr(s)
  force(s[
1])
end
def stream_null?(s)
  s.nil? 
or s==[]
end
    用Ruby中的数组充当“粘合剂”,stream_car直接返回第一个元素,而stream_cdr需要用force求值表达式,履行承诺。另外,将空数组[]作为the-empty-stream。再定义几个高阶函数,map和foreach,其他如filter与此类似:
def stream_enumerate_interval(low,high)
  
if low>high
    
return []
  
else
    cons_stream(low,stream_enumerate_interval(low.succ,high))     
  end
end
def stream_ref(s,n)
  
if n==0
    stream_car(s)
  
else
    stream_ref(stream_cdr(s),(n
-1))     
  end
end
def stream_map(proc,s)
  
if stream_null?(s)
    []
  
else
    cons_stream(proc.call(stream_car(s)),stream_map(proc,(stream_cdr(s))))    
  end
end
def stream_for_each(proc,s)
  
if stream_null?(s)
    :done
  
else
    proc.call(stream_car(s))
    stream_for_each(proc,stream_cdr(s))     
  end
end
def display_stream(s)
  stream_for_each(
lambda{|item| puts item},s)
end
def stream_filter(pred,s)
  
if stream_null?(s)
    []
  elsif pred.call(stream_car(s))
    cons_stream(stream_car(s),stream_filter(pred,stream_cdr(s)))
  
else
    stream_filter(pred,stream_cdr(s))   
  end
end

    最后,看下例子:
puts "s:"
s
=stream_enumerate_interval(1,5)
display_stream(s)
puts 
"odd_s:"
odd_s
=stream_filter(lambda{|x| x%2==1},s)
display_stream(odd_s)
puts 
"ss:"
ss
=stream_map(lambda{|x|x*x},s)
display_stream(ss)



posted @ 2008-05-08 22:32 dennis 阅读(1249) | 评论 (0)编辑 收藏

    前段时间看了这篇文章《Ropes:理论与实践》。这两天为了提高工作中某个系统对外接口的效率,才认真学习了一番。本质上Ropes是将字符串表示为一棵二叉树,特别适用于长字符串的处理,貌似c++ STL库中也有这么个实现。具体实现和原理还是看这篇paper。《Ropes:理论与实践》一文中给出的测试数据相当惊人,Ropes比之String和StringBuffer在append,insert,delete等操作上的效率都有一个数量级以上的差距。跑下作者给出的测试程序,其实在测试的字符串不是很长的情况下,这个差距并没有那么大,这也从侧面说明了Rope的应用范围:即只有在大量修改大型字符串的应用程序中才能看到明显的性能提升。那么是否可以用Rope替代StringBuffer做append生成字符串(比如我要的生成xml)。作者也说啦:
  “由于 Rope 的附加性能通常比 StringBuffer 好,这时使用 rope 是否有意义呢?答案还是否。不论何时将输入的数据组合在一起形成格式化输出时,最漂亮最有效的方法是使用模板引擎(例如 StringTemplate 或 FreeMarker)。这种方法不仅能干净地将表示标记与代码分开,而且模板只进行一次编译(通常编译为 JVM 字节码),以后可以重用,从而使它们拥有极佳的性能特征。”

    我用Rope for java替代了StringBuffer做XML生成,效率提升在5%-30%左右,xml字符串不是很长,这个提升显然有限,也带来了不必要的复杂度。因此最后还是用Velocity模板引擎来生成XML,测试的结果效率并没有多少改善,但是显然更容易维护和开发了。回到Rope的话题,我用Ruby实现了个版本,Rubyforge上有一个Rope的实现,但是看了源码,与paper所述算法有点差异,因此照着Rope for java也实现了一个Rope4r。测试的结果证明在长字符串的累积操作上,Rope4r的append比之String的+=性能可以快上3倍左右,而如果采用String的<<操作,不是immutable的,当然是最快了;比较郁闷的是slice和insert操作都比String的慢上几倍,因为Ruby的String、Array的内建对象都是直接用c写成并做了优化的,我猜测原因在这。


posted @ 2008-05-05 18:41 dennis 阅读(3435) | 评论 (0)编辑 收藏

    我们现在做的项目是典型的小型项目,整个组也就4、5个人,一个迭代周期基本在两周左右。尽管没有明确有“迭代”这么说法,却是以业务人员的策划案做分期实现。这个分期,按我的理解其实就是迭代。最近发现的一个问题是,在迭代开始后,业务人员却没有办法保证需求在这个迭代周期完成前的稳定性,甚至在各个模块集成之前,大家就提出N多意见,并且这些意见很多时候都是前后矛盾的。特别是在客户端的开发上,显然,客户端UI和操作习惯方面是最多变的地方。可怜我们公司唯一的MM程序员快陷入变更频繁的泥潭了,改过去改回来是家常便饭。其实也是她过于老实,要我来说,你们要改,可以,但是我要向业务人员确认,他是我唯一的变更来源,你们有什么需求向他反应,他来收集和甄别。在《敏捷软件开发》中说到,迭代开始后,客户就同意不再更改当次迭代中的素材的定义和优先级别,可惜这一点貌似很难做到了,业务人员经常屈从于管理层或者其他小组意见的压力。在我看来,在当次迭代完成前的所有建议或者说需求,都可以收集起来,由业务人员负责收集、甄别和决定,放入下一个迭代版本的开发,因为我们的迭代周期一般也在两周左右,这个周期足够辨别这些需求的合理性和响应需求的及时性,而不是像现在这样大家七嘴八舌地提意见,技术人员疲于奔命,乃至于发脾气(入夏真是脾气坏的季节);系统各部分迟迟无法进行集成测试,造成新的修改意见没有做完,预定的迭代版本的更无法按时完成的局面。

posted @ 2008-04-28 21:04 dennis 阅读(1717) | 评论 (4)编辑 收藏

    山僧昔在双径归堂,未及一月,忽于睡中疑著万法归一,一归河处?自此疑情顿发,废寝忘食,东西不辨,昼夜不开,开单展钵,屙屎放尿,至于一动一静,一语一 默,总只是个一归何处,更无丝毫异念,了不可得。正如钉钉胶粘,摇撼不动,虽在稠人广众之中,如无一人相似。从朝至暮,从暮至朝,澄澄湛湛,卓卓巍巍,纯 清绝点,一会万年,境寂人忘,如痴如兀,不觉至第六日,随众在三塔讽经次,抬头看见五祖演和尚真,蓦然触发日前仰山老和尚问拖死尸句子,直得虚空粉碎,大 地平沈,物我两忘,如镜照境,百丈野狐,狗子佛性,青州布衫,女子出定语,从头密举验之,无不了了。般若妙用,信不诬矣。(见《古尊宿语录》)

    想来王阳明龙场悟道的感觉也不过如此。王阳明的心学归结就是“致良知”三个字,不说“致”,仅“良知”二字就是何等宝贵?看看安徽阜阳儿童们的命运,这个接二连三发生诡异事件的地方,当地的公仆们可有“良知”在心中?我们保留了文化传统,却抛弃了传统文化。

posted @ 2008-04-28 17:33 dennis 阅读(491) | 评论 (0)编辑 收藏

     在blogjava和javaeye上的两个blog的顶部广告都售出了,热烈庆祝:) 准备啥时候去绑定个支付宝,把我的一块五毛钱取出来,刚好够买两个包子 。还是阿里妈妈好,来的实在,google广告的1.2美元这辈子看来是指望不上了,人民币还在持续升值中......

posted @ 2008-04-23 09:38 dennis 阅读(405) | 评论 (2)编辑 收藏

    推荐两篇blog:
《java NIO 类库selector机制解析(上)》
《java NIO 类库selector机制解析(下)》

    有一个奇怪的现象引出的话题,为了Selector.wakeup功能做到跨平台,每个Selector.open()时,在Windows会建立一对自己和自己的loopbackTCP连接;在Linux上会开一对pipepipeLinux下一般都是成对打开)。java为了跨平台真是无所不用其极,此中冷暖谁知啊。

posted @ 2008-04-22 18:12 dennis 阅读(546) | 评论 (0)编辑 收藏

    最近碰到个需求,计算游戏得分的规则,类似这样:

游戏人数

第一名获得赌注

第二名获得赌注

第三名获得赌注

第四名获得赌注

二人

100%

0%

二人(出现2个第1名时)

50%

50%

 

 

三人

70%

30%

0%

三人出现3个第1名时

33.3333%

33.3333%

33.3333%

 

三人(出现2个第1名时)

50%×2

0%

 

 

......
......
    这些奖励规则没有什么规律,随着人数增多,就越发复杂了,并且业务人员可能随时改变这些规则。
    显然,奖励规则可以采用策略模式,定义策略接口,根据游戏人数定义不同的规则,本质上就是利用动态的多态调用。可以想见,还是少不了复杂的case...when语句,以及繁多的代码。恰好最近读《unix编程艺术》和《代码大全2》,两者都提到一个结论:人类阅读复杂数据结构远比复杂的控制流程容易,或者说数据驱动开发是非常有价值的。《代码大全2》声称这个是表驱动法。因此,这个奖励系数的计算,能否转化成一个查表过程呢?注意到,在游戏中,名次是根据个人的积分在所有玩家中的排位来决定,大概会有这么个排序的玩家积分数组[100,50,3],这个数组表示3个玩家,第一名100分,第二名50分,第三名才3分。依据规则,第一名的奖励系数就是0.7,第二名就是0.3。我想到类似这样的数组其实都有个形式表示它们的内置结构,比如[100,50,3]数组的“结构”是"111",代表3个位置都有一个人。将"111"作为关键码去查表不就OK了?
    将每个排好序的积分数组解码为这样的关键码,然后去查预先写好的奖励系数表,这个奖励系数表大概类似:
  @@award_rate_hash={
    :
"2"=>{
      :
"11"=>{:"1"=>1,:"2"=>0},
      :
"20"=>{:"1"=>0.5,:"2"=>0.5}
    },
    :
"3"=>{
      :
"111"=>{:"1"=>0.7,:"2"=>0.3,:"3"=>0},
      :
"300"=>{:"1"=>0.33},
      :
"201"=>{:"1"=>0.5,:"3"=>0},
      :
"120"=>{:"1"=>1,:"2"=>0}
    },
    :
"4"=>{
      :
"1111"=>{:"1"=>0.65,:"2"=>0.30,:"3"=>0.05,:"4"=>0},
      :
"4000"=>{:"1"=>0.25},
      :
"3001"=>{:"1"=>0.33,:"4"=>0},
      :
"1300"=>{:"1"=>1,:"2"=>0},
      :
"2020"=>{:"1"=>0.5,:"3"=>0},
      :
"1201"=>{:"1"=>0.7,:"2"=>0.15,:"4"=>0},
      :
"1120"=>{:"1"=>0.7,:"2"=>0.3,:"3"=>0},
      :
"2011"=>{:"1"=>0.35,:"3"=>0.3,:"4"=>0}
    }      
  }
    一个三级hash表,首先根据玩家人数查到特定的系数表,比如要查3个玩家、积分数组是[100,50,3]的奖励系数表就是  @@award_rate_hash[:"3"],然后积分数组[100,50,3]解码为:"111",继续查,如此规则的奖励系数表就是@@award_rate_hash[:"3"][:"111"]——也就是 {:"1"=>0.7,:"2"=>0.3,:"3"=>0},那么查积分是100的玩家系数就是@@award_rate_hash[:"3"][:"111"][([100,50,3].index(100)+1).to_s.to_sym],也就是:"1"=>0.7[100,50,3].index(100)+1就是积分100的玩家在数组中的名次(即1),也就是:"1"指向的结果0.7。其他玩家的查表过程与此类似,不细说了。
    这样,我们所有的奖励规则就是维护这么一张hash表,这个表看起来复杂,其实完全可以自动生成,让业务人员来提供样例数据,解码样例数据并生成这个表是很简单的事情。积分数组的“解码”,我给一个Ruby版本:
   #解码数组为字符串关键码
  def decode_array(array)
    len
=array.size
    trace_list
=[]
    result
=[]
    len.times do 
|time|
      result[time]
=0   
      trace_list[time]
=false
    end
    array.each_with_index do 
|item,index|
      result[index]
=count_times(array,trace_list,index,len)
    end
    
return result.join('').to_sym
  end
  
def count_times(array,trace_list,index,len)
    item
=array[index]
    result
=0
     (index..len).each do 
|i|
      
if array[i]==item and !trace_list[i]
        result
+=1
        trace_list[i]
=true
      end
    end
    
return result
  end


posted @ 2008-04-17 19:50 dennis 阅读(4191) | 评论 (1)编辑 收藏

仅列出标题
共56页: First 上一页 26 27 28 29 30 31 32 33 34 下一页 Last