ImageVerifierCode 换一换
格式:DOCX , 页数:38 ,大小:33.43KB ,
资源ID:9081904      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9081904.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(程序员编程艺术.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

程序员编程艺术.docx

1、程序员编程艺术程序员编程艺术 程序员编程艺术第一二十七章集锦与总结 教你如何编程 作者July编程艺术室 时间comcom 出处httpcomv_JULY_v 声明版权所有侵权定究 本文档制作者有鱼com CEO 吴超 花明月暗 前言 围绕面试算法编程三个主题的程序员编程艺术系列简称TAOPP 系列从 今年4 月写第一篇起至今快有一年近1 年的创作中写了二十七章共计22 篇文章 这是本人的第4 大原创作品不过与之前微软面试100 题系列红黑树系列及十三个经 典算法研究系列相比编程艺术系列的某些篇文章的作者除了我本人自己或多或少还得到 了不少朋友的支持我把这些朋友组织起来成立了一个工作室它的名字

2、叫做编程艺术室 编程艺术系列最初名为程序员面试题狂想曲即为面试服务后来随着加入与我一起创 作的人越来越多我们逐渐意识到为面试服务不应该成为我们最终或最主要的目的而应 该注重提高广大初学者的编程能力以及如何运用编程技巧和高效的算法解决实际应用问 题这才是计算机科学与编程的本质于是我们便把程序员面试题狂想曲系列更名为程序 员编程艺术系列然后把狂想曲创作组确定为编程艺术室并提出了我们的宗旨即如下 编程艺术室致力于以下三点工作 1 针对一个问题不断寻找更高效的算法并予以编程实现 2 解决实际中会碰到的应用问题 3 经典算法的研究与实现 总体突出一点编程如何高效的编程解决实际问题 刚开始的时候我们是不敢

3、给自己戴艺术这个高帽子的因为艺术的提炼是一个非常非 常艰难的过程且我们全部都是一群庸人但是我们很想也非常乐意接受这个挑战所以 一边带着万分的惶恐一边认真细心的创作每一章等到发布后再对每一章任何一个细节 1 仔细推敲与琢磨反复思考反复修正反复完善绝不轻易放过任何一个问题漏洞和 bug但即便如此仍然冒出了很多的问题幸运的是有广大的读者朋友们对编程艺术系 列和我们给予热心的指导与优化建议更重要的是他们还耐心细致的对编程艺术系列提出了 非常多的且异常宝贵的批评指正与修订完善的意见 没有编程艺术室全部人员的加入创作编程艺术系列将比现在所呈现在大家面前的还要 糟糕至少我个人现在是这么认为的而如果没有众多网

4、友朋友们的修正与完善编程 艺术系列将更显不足从而失去它本身该有的持久动力与明天所以非常感谢所有热心的 朋友给予编程艺术系列所有的指导和意见你们的反馈给了我们的创作很大很大的帮助同 时也感谢本社区编辑的推荐非常感谢最后恳请广大读者对编程艺术系列继续监督 并随时予以批评指正我们不能残留任何一个bug因为编程艺术系列最后可能要写到第 六十章谢谢 ok以下是已经写了的编程艺术系列的前二十七章共21 篇文章希望你能从中感受到 编程的技巧与乐趣点击链接即可跳转到相应页面 无私分享造福天下 第一章左旋转字符串 4 第二章字符串是否包含及相关问题扩展 34 第三章寻找最小的k 个数 63 第三章续Top K

5、算法问题的实现 107 第三章再续快速选择SELECT 算法的深入分析与实现 148 第三章三续求数组中给定下标区间内的第K 小大元素 167 第四章现场编写类似strstrstrcpystrpbrk 的函数 178 第五章寻找满足条件的两个或多个数 195 第六章亲和数问题-求解500 万以内的亲和数 208 第七章求连续子数组的最大和 215 第八章从头至尾漫谈虚函数 222 第九章闲话链表追赶问题 237 第十章如何给107 个数据量的磁盘文件排序 246 第十一章最长公共子序列 LCS 问题 280 第十二十五章中签概率IP 访问次数回文等问题初稿 291 第十六第二十章全排列跳台阶奇

6、偶排序第一个只出现一次等问题 305 2 第二十一二十二章出现次数超过一半的数字最短摘要的生成 322 第二十三四章杨氏矩阵查找倒排索引关键词Hash 不重复编码实践 340 第二十五章二分查找实现Jon Bentley 90程序员无法正确实现 363 第二十六章基于给定的文档生成倒排索引的编码与实践 366 第二十七章不改变正负数之间相对顺序重新排列数组时间O N 空间O 1 393 编程艺术室 编程艺术系列已经发布的上二十七章仍有很多很多的问题与不足但永久勘误永久 优化如果读者朋友对编程艺术系列任何一章有任何问题和建议或者发现了以上任何一 章的问题错误漏洞和bug欢迎及时反馈给我们我们将感

7、激不尽当然如果有兴 趣我们也欢迎您加入我们-编程艺术室 1 编程能力较强 2 有一定的业余时间 3 工作经验越长越好能力出众的在读研究生或ACM 人员也可以考虑 4 愿意分享平时工作中的项目经验或性能优化建议 5 热爱算法者优先 符合以上条件的朋友欢迎加入编程艺术室有意者可给我zhoulei0907yahoocn 投一 篇稿子 稿子主题内容形式不限只要你觉得自己能写出像已有的27 章那样的文章便 可投稿审阅之后邀请加入以为大家创造更多的价值更好的服务谢谢 版权所有XX严禁用于任何商业用途违者定究法律责任 特别提醒 本编程艺术系列文档中有任何一处错误bug或漏洞读者朋友一经发现欢迎随时 来信指导

8、或blog 内留言评论我将感激不尽 我的联系方式如下 邮箱zhoulei0907yahoocn 微博httpweibocomjulyweibo Bloghttpcomv_JULY_v 本结构之法算法之道blog若无意外永久更新永久勘误 感谢关注本编程艺术系列的读者朋友们感谢所有编程艺术室内的朋友咱们 blog 上 第二十八章再见 3 第一章左旋转字符串 作者Julyyansha 时间二零一一年四月十四日 说明狂想曲有三层意思1思绪纷飞行文杂乱无章想到什么记下什么2简单问题深入 化复杂问题精细化不惧汪洋不惧艰深洋洋洒洒纵横千里3依托一道面试题展开来思维放任 不羁逐步深入细致入微反复修正绝不含糊以

9、期给读者一个彻彻底底明明白白的交待原为狂想 曲现在已改为编程艺术系列 微博httpweibocomjulyweibo 出处httpcomv_JULY_v 序 前言 第一节左旋转字符串 第二节两个指针逐步翻转 第三节通过递归转换缩小问题之规模 第四节stlrotate 算法的步步深入 第五节总结 序 一个懒散的午夜程序员躺在椅子上静静点上一支烟瞅着屏幕上那一行一行如行云 流水般的代码赏心悦目渐觉困意便慢慢闭上了俩眼养神 而后冥冥中房间里似缓缓响起一首钢琴曲叫不出名字却铿锵有力且清脆无比忽 而激荡忽而平静激荡处如波涛翻滚怒洋咆哮平静处如潺潺流水鸟语花香 半响程序员突然睁开双眼关掉编译器打开记事本信

10、笔由缰急速记录下他那杂 乱无章和奇特跳跃的思绪他怕此刻不赶紧记下来以后风吹云散于是世间就有 了程序员面试题狂想曲一乐章的诞生 此曲终日弹奏绵绵不绝终至广为流传飘进了千万人的耳中余音不去 前言 4 本人整理微软等公司面试100 题系列包括原题整理资源上传帖子维护答案整理 勘误修正与优化工作包括后续全新整理的80 道总计180 道面试题已有半年的时间 了 关于这180 道面试题的一切详情请参见横空出世席卷Csdn 评微软等数据结构 算法面试180 题 一直觉得这180 道题中的任何一题都值得自己反复思考反复研究不断修正不断 优化之前的答案整理由于时间仓促加之受最开始的认识局限更兼水平有限所以这 1

11、80 道面试题的答案有很多问题都值得进一步商榷与完善 特此想针对这180 道面试题再写一个系列叫做程序员编程艺术系列如你所见 我一般确定要写成一个系列的东西一般都会永久写下去的 他似风儿一般奔跑很多人渐渐的停下来了而只有他一直在飞一直在飞 ok本次程序员编程艺术系列以之前本人最初整理的微软面试100 题中的第26 题左 旋转字符串为开篇希望就此问题进行彻底而深入的阐述然以下所有任何代码仅仅只是 全部测试正确了而已还有很多的优化工作要做欢迎任何人不吝赐教谢谢 第一节左旋转字符串 题目描述 定义字符串的左旋转操作把字符串前面的若干个字符移动到字符串的尾部 如把字符串abcdef 左旋转2 位得到字

12、符串cdefab 请实现字符串左旋转的函数要求对长度为n 的字符串操作的时间复杂度为 O n 空间复杂度为O 1 编程之美上有这样一个类似的问题咱们先来看一下 设计一个算法把一个含有N 个元素的数组循环右移K 位要求时间复杂度为O N 且只允许使用两个附加变量 分析 5 我们先试验简单的办法可以每次将数组中的元素右移一位循环K 次 abcd12344abcd12334abcd12234abcd11234abcd RightShift int arr int N int K while K- int t arrN - 1 for int i N - 1 i 0 i - arri arri - 1

13、 arr0 t 虽然这个算法可以实现数组的循环右移但是算法复杂度为O K N不符合题目的要 求要继续探索 假如数组为abcd1234循环右移4 位的话我们希望到达的状态是1234abcd 不妨设K 是一个非负的整数当K 为负整数的时候右移K 位相当于左移-K位 左移和右移在本质上是一样的 解法一 大家开始可能会有这样的潜在假设K N事实上很多时候也的确是这样的但严格来说 我们不能用这样的惯性思维来思考问题 尤其在编程的时候全面地考虑问题是很重要的K 可能是一个远大于N 的整数在这个 时候上面的解法是需要改进的 仔细观察循环右移的特点不难发现每个元素右移N 位后都会回到自己的位置上因此 如果K

14、N右移K-N 之后的数组序列跟右移K 位的结果是一样的 进而可得出一条通用的规律 右移K 位之后的情形跟右移K K N 位之后的情形一样如代码清单2-34 所示 代码清单2-34 RightShift int arr int N int K K N while K- 6 int t arrN - 1 for int i N - 1 i 0 i - arri arri - 1 arr0 t 可见增加考虑循环右移的特点之后算法复杂度降为O N 这跟K 无关与题目 的要求又接近了一步但时间复杂度还不够低接下来让我们继续挖掘循环右移前后数组 之间的关联 解法二 假设原数组序列为abcd1234要求变换

15、成的数组序列为1234abcd即循环右移了4 位 比较之后不难看出其中有两段的顺序是不变的1234 和abcd可把这两段看成两个整 体右移K 位的过程就是把数组的两部分交换一下 变换的过程通过以下步骤完成 逆序排列abcdabcd1234 dcba1234 逆序排列1234dcba1234 dcba4321 全部逆序dcba4321 1234abcd 伪代码可以参考清单2-35 代码清单2-35 Reverse int arr int b int e for b e b e- int temp arre arre arrb arrb temp RightShift int arr int N

16、int k K N Reverse arr 0 N K - 1 Reverse arr N - K N - 1 7 Reverse arr 0 N - 1 这样我们就可以在线性时间内实现右移操作了 稍微总结下 编程之美上 限制书中思路的根本原因是题目要求且只允许使用两个附加变量去掉这个限制 思路便可如泉喷涌 1第一个想法 是一个字符一个字符的右移所以复杂度为O NK 2后来它改进了通过这条规律右移K 位之后的情形跟右移K K N 位之后的情 形一样 复杂度为O N2 3直到最后它才提出三次翻转的算法得到线性复杂度 下面你将看到本章里我们的做法是 1三次翻转直接线性 2两个指针逐步翻转线性 3s

17、tl 的rotate 算法线性 好的现在回到咱们的左旋转字符串的问题中来对于这个左旋转字符串的问题咱们可 以如下这样考虑 11思路一 对于这个问题咱们换一个角度可以这么做 将一个字符串分成两部分X 和Y 两个部分在字符串上定义反转的操作XT 即把X 的 所有字符反转如X abc 那么XT cba 那么我们可以得到下面的结论 XTYT T YX显然我们这就可以转化为字符串的反转的问题了 不是么ok就拿abcdef 这个例子来说非常简短的三句请细看一看就懂 1首先分为俩部分Xabc Ydef 2X- XTabc- cba Y- YTdef- fed 3 XTYT T YXcbafed- defab

18、c即整个翻转 我想这下你应该了然了 然后代码可以这么写已测试正确 1 Copyright 小桥流水 July 8 2 c 代码实现已测试正确 3 httpsmallbrcom20110313100E9A298 4 _21-E5B7A6E6978BE8BDACE5AD97E7ACA6E4B8B26html 5 Julyupdatedcom 6 include 7 include 8 9 char invert char start char end 10 11 char tmp ptmp start 12 while start NULL end NULL start end 13 14 tmp

19、 start 15 start end 16 end tmp 17 start 18 end - 19 20 return ptmp 21 22 23 char left char s int pos pos 为要旋转的字符个数或长度下面主函数测试中 pos 3 24 25 int len strlen s 26 invert s s pos - 1 如上X- XT即 abc- cba 27 invert s pos s len - 1 如上Y- YT即 def- fed 28 invert s s len - 1 如上整个翻转 XTYT T YX 即 cbafed- defabc 29 re

20、turn s 30 31 32 int main 33 34 char s abcdefghij 35 puts left s 3 36 return 0 37 12答案V03 版中第26 题勘误 之前的答案V03 版第21-40 题答案 中第26 题贴的答案有误那段代码的问题最 早是被网友Sorehead 给指出来的 9 第二十六题 楼主的思路确实很巧妙我真没想到还有这种方法学习了 不过楼主代码中存在问题主要是条件判断部分 函数LeftRotateString 中 if nLength 0 n 0 n nLength 函数ReverseString 中 if pStart NULL pEnd

21、 NULL 当时以答案整理因时间仓促及最开始考虑问题不够周全为由没有深入细看下去 后来朋友达摩流浪者再次指出了上述代码的问题 26 题 这句 if nLength 0 n 0 n nLength 有问题吧 还有一句应该是if pStart NULL pEnd NULL 吧 而后修改如下已测试正确 1 zhedahht 2 Julykupdated 3 copyright comby July 4 引用请注明原作者出处 5 include 6 include 7 using namespace std 8 9 void Swap char achar b 特此把交换函数独立抽取出来当然不排除会

22、有人认为此为多此一举 10 11 char temp a 12 a b 13 b temp 14 15 16 Reverse the string between pStart and pEnd 17 void ReverseString char pStart char pEnd 18 19 if pStart 0 pEnd 0 20 这句也可以是if pStart NULL pEnd NULL 21 22 while pStart pEnd 23 24 Swap pStartpEnd 交换 25 26 pStart 27 pEnd- 10 28 29 30 31 32 Move the f

23、irst n chars in a string to its end 33 char LeftRotateString char pStr unsigned int n 34 35 if pStr NULL 36 37 int nLength static_cast strlen pStr 38 if nLength 0 n 0 n nLength n 可以 0也可以说不该 0 39 nLength 是整个字符串的长度n 是左边的一部分所以应该是 n nLength 40 之前上传的答案代码就错在这里最初的为n nLength当然 就是错的了Julykupdated 41 42 char p

24、FirstStart pStr 43 char pFirstEnd pStr n - 1 44 char pSecondStart pStr n 45 char pSecondEnd pStr nLength - 1 46 47 reverse the first part of the string 48 ReverseString pFirstStart pFirstEnd 49 reverse the second part of the strint 50 ReverseString pSecondStart pSecondEnd 51 reverse the whole string

25、 52 ReverseString pFirstStart pSecondEnd 53 54 55 return pStr 56 57 58 int main 59 60 char a11 hello July 2修正以一个数组实现存储整个字符串 61 char ps a 62 LeftRotateString ps 6 63 for ps 0ps 64 cout ps 65 cout endl 66 ps NULL 代码规范 67 return 0 68 11 上述修正的俩处错误如下所示 1如上注释中所述 if nLength 0 n nLength nLength 是整个字符串的长度吧n

26、是左边的一部分所以应该是n nLength 2至于之前的主函数为什么编写错误请看下面的注释 int main char ps hello July 本身没错但你不能对ps 所指的字符串做任何修改 这句其实等价于const char ps hello July LeftShiftString ps 4 而在这里试图修改ps 所指的字符串常量所以将出现错误 puts ps return 0 当然上面的解释也不是完全正确的正如ivan 所说从编程实践来说不完全对 如果在一个大的工程里面你怎么知道ps 指向的是字符串还是malloc 出来的东西 那么如何决定要不要对ps 进行delete 不过至少第2

27、6 题的思路一的代码最终完整修正完全了 13updated 可能你还是感觉上述代码有点不好理解ok下面再给出一段c 实现的代码 然后我们可以看到c 的高效与简洁 1 copyright yiyibuptJuly 2 已测试正确Julyupdatedcom 3 不要小看每一段程序July 4 include 5 include 6 7 void rotate char start char end 8 9 while start NULL end NULL start end 10 11 char temp start 12 start end 13 end temp 14 start 15 e

28、nd- 12 16 17 18 19 20 void leftrotate char pint m 21 22 if p NULL 23 return 24 int len strlen p 25 if m 0m len 26 27 char xfirstxend 28 char yfirstyend 29 xfirst p 30 xend pm-1 31 yfirst pm 32 yend plen-1 33 rotate xfirstxend 34 rotate yfirstyend 35 rotate pplen-1 36 37 38 39 int main void 40 41 cha

29、r str abcdefghij 42 leftrotate str3 43 printf snstr 44 return 0 45 第二节两指针逐步翻转 先看下网友litaoye 的回复26左旋转字符串跟panda 所想是一样的即 以abcdef 为例 1 ab- ba 2 cdef- fedc 原字符串变为bafedc 3 整个翻转cdefab 只要俩次翻转且时间复杂度也为O n 13 21在此本人再奉献另外一种思路即为本思路二 abc defghi要abc 移动至最后 abc defghi- def abcghi- def ghiabc 定义俩指针p1 指向ch0p2 指向chm 一下过程循环m 次交换p1 和p2 所指元素然后p1 p2 第一步交换abc 和def abc defghi- def abcghi 第二步交换abc 和 ghi

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1