2008年11月13日 星期四

循环移位问题--巧妙的解答和证明

前几天订的《Programming Pearls》今天送到了,拿到书之后忍不住放下正在复习的英语书(下周有英语考试),开始翻看起来,哪知道只是随便一看就看了20多页,因为是原版书,开着金山词霸边看变查,所以看得比较慢。不过书真的写的很好,看了前两卷的四个小问题,每个小问题的解决都很巧妙,尤其是下面这个问题:
.....

考虑一个字符串abcdefgh,我们让它循环左移三位,那么就得到defghabc,问题就是给定一个长度为n的字符串,让其循环左移k次,求移位后的字符串。

显然,这是一个非常简单的问题,我想任何一个学过编程的人都能解决,现在我们给它加点限制条件,不能借助其它的存储空间,也就是说字符只能在这个字符串上移动,进行 “就地” 移位。

分析该问题,可以发现其本质就是将一个字符串分成两个字串ab,其中a包含前k个字符,而b包含其余字符,然后将字符串变为ba。

下面给出解决方法:
首先,我们可以很容易的实现字符串的就地逆转操作,比如abcd逆转为dcba只要依次将第一个和最后一个交换,第二个和倒数第二个交换……

有了逆串操作后,我们可以先将a逆转,得到a' 再将b 逆转得到 b',然后将整个串a'b' 逆转,得到(a'b')' ,可以证明,这个串就是ba。
这个式子是不是很有趣,有点像矩阵转置规则吧。

其实这个方法已经在网上流传好久了,不过我之前费了很大的劲去想为什么这样就可以了呢,今天在书上看到了简洁而强大的证明:
这个证明只有一幅图,伸出你的左右手,按下图中所示去做,你会发现,原来这么简单!

4 评论:

tino 说...

菜鸟认为:如果把那个移位的方法变换一下顺序:先把ab逆转成b'a',再将b'逆转成b,a'逆转成a,应该会更容易理解一些
:)

madongfly 说...

两种解释方法其实没区别,只是那个证明很好,简单,明了……

王永亮 说...

这个书很好么?
最近我定了一本c++ primer
好书!!!

madongfly 说...

嗯,那本书我有也有,不过一直没细看……
主要也是为了练E文才买的这本书,关键是它看上去很薄,而且讲的东西也比较有意思。

发表评论