编程珠玑

编程珠玑:插入排序优化

余生长醉 提交于 2021-01-14 02:42:45
插入排序的精髓就是首先将第一个元素视为有序子数组x[0...0],然后插入x[1]...x[n-1].思想很简单,代码也很简单,简单的代码有没有优化的空间呢?编程珠玑中提供了几个优化后的方案,效率提高了70%之多。 简单的实现(sort1) void insertSort(int *array, size_t size) { for(size_t i = 1; i < size; i++) { for(int j = i; j > 0 && array[j - 1] > array[j]; j--) { swap(array[j - 1], array[j]); } } } 优化思路 内循环的swap函数可能不如内联函数快些,所以第一步优化将该swap函数展开,据作者说,展开后效率提高了60%。 优化代码(sort2) void insertSort(int *array, size_t size) { for(size_t i = 1; i < size; i++) { for(int j = i; j > 0 && array[j - 1] > array[j]; j--) { int t = array[j]; array[j] = array[j - 1]; array[j - 1] = t; } } } 优化思路 由于内循环中总是给变量t赋同样的值(x[i]的初始值)

编程珠玑总结

大憨熊 提交于 2020-04-04 06:09:00
一、排序 1、应用 a、一些程序需要有序的输出,二分查找之类的程序需要一个有序的输入。 b、收集相同项:使用排序来收集序列中相同的项,后缀数组收集相同的单词。 2、算法 a、插入排序:O(n^2)的最坏时间,如果给一个大致有序的数组进行排序,则只需要O(n)时间,是稳定的。 b、快速排序:最优时间O(nlogn),最坏情况O(n^2)时间O(n)空间 c、堆排序:任何情况都是O(nlogn)时间 d、其他:归并排序,选择排序,希尔排序 e、基数排序 f、位图排序:序列中的整数在一个范围内,没有重复的数,没有额外的数据。 二、查找 1、算法 a、线性查找 b、二分查找:有序数组 c、哈希 d、二叉查找树 e、关键字索引:bins,bit vectors f、其他:通过cache减少时间 三、其他 解决含有重复元素的n个元素的集合问题 a、优先队列:有insert和extractmin操作,使用堆 b、选择:选择k个最小的元素 四、字符串算法 a、找出文本中中不同的单词和每个单词出现的次数:使用map 或者 使用哈希 b、寻找文本中重复子字符串中最长的一个:使用后缀数组 c、生成随机文本:使用后缀数组,马尔科夫链 五、向量矩阵算法 六、随机数 七、数值算法 代码优化方案 一、空间换时间 1、扩张数据结构,增加额外信息,或者改变更加合适的数据 2、存储预先计算好的结果 3、caching

《编程珠玑》第二章:啊哈!算法——左旋转&&变位词

筅森魡賤 提交于 2020-03-19 13:28:25
3 月,跳不动了?>>> 本章讲解的是算法的作用,“看起来很困难的问题也可以有一个简单的、意想不到的答案。”在任何愿意在编程之前、之中和之后进行认真思考的程序员都有机会捕捉到这灵光一闪。 文章从三个问题展开,我独自先思考了一下,发现解决方法都是比较低效的,既浪费空间也浪费时间。 a. 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数(在文件中至少缺少一个这样的数,为什么? 就是2 32 > 40亿 所以就是有至少缺少一个 )。在具有足够内存的情况下,如何解决该问题?如果有几个外部的“临时”文件可用,但是仅有几百字节的内存,又该如何解决该问题? b. 将一个n元一维向量左旋转i个位置。例如,当n=8且i=3时,向量abcdefgh旋转为defghabc。简单的代码使用一个n元的中间变量在n步内完成该工作。你能否仅使用数十个额外字节的存储空间,在正比于n的时间内完成向量的旋转? c. 给定一个英语词典,找出其中的所有变位词集合。例如,“pots","stop"和“tops"互为变位词,因为每个单词都可以通过改变其他单词中字母的顺序来得到。 对于a题,第一时间应该是想到“ 二分搜索 ”这个方法。在log n时间内完成对顺序文件的搜索。但因为前提是要顺序,所以这也是二分搜索的一个弊端。因为要对非排序的整数排序,至少是需要n的正比时间。此题所提到的

编程珠玑:向量旋转(旋转交换)

大兔子大兔子 提交于 2020-03-19 13:04:16
3 月,跳不动了?>>> 问题描述 请将一个具有n个元素的一维向量向左旋转i个位置。例如,假设n=8,i=3,那么向量abcdefgh旋转之后得到向量defghabc。简单编码使用一个具有n个元素的中间向量分n步即可完成此作业。你可以仅使用几十字节的微小内存,花费与n成比例的时间来旋转该向量吗? 解决思路 方案一: 将向量x中的前i个元素复制到一个临时数组中,接着将余下的n-i个元素左移i个位置,然后再将前i个元素从临时数组中复制回x中的后面位置。 该方案使用了i个额外的位置,如i足够大,过于浪费空间。 方案二: 定义一个函数来将x向左旋转一个位置,然后调用该函数i次。 该方案需要将数组移到i将,过于浪费时间。 方案三: 先将x[0]移临时变量t中,然后将x[i]移到x[0]中,x[2i]移到x[i]中,依次类推,直到我们又回到从x[0]中提取元素,不过在这时我们要从t中提取元素,然后结束该过程。当i=3,n=12时,该阶段将以下面的次序移到各个元素。 如果该过程不能移动所有的元素,那么我们再从x[1]开始移动,一直依次进行下去,直到移动了所有的元素时为止。 该方案过于精巧,像书中所说的一样堪称巧妙的杂技表演,非常容易出错。 方案四: 旋转向量x实际上就是将向量ab的两个部分交换为向量ba,这里a代表x的前i个元素。假设a比b短。将b分割成b l 和b r ,使b r

编程珠玑第一部分基础

≯℡__Kan透↙ 提交于 2020-03-05 00:11:13
算法基础 问题定义:正确明确问题是什么 时间—空间折中与双赢:尽可能的减少时间和空间 简单的设计:尽可能的简单但不要过于简单 算法设计 排序:排序最显而易见的用处是产生有序的输出,该输出既可以是系统规范要求的一部分,也可以是另一个程序(例如二分搜索程序)的前期准备工作。 标识:当使用等价关系来定义类时,定义一种标识使得类中的每一项都具有相同的标识。而该类以外的其他项则没有该标识。 数据结构选择 将大程序缩减为小程序。正确的数据结构设计可以节省时间和空间、提高可移植性和可维护性。 注:程序员在节省空间方面无计可施时,将自己从代码中解脱出来,退回七点并集中心力研究数据,常常能有奇效。(数据的)表示形式是程序设计的根本 下面是退回起点进行思考时的几条原则。 使用数组重新编写重复代码。冗长的相似代码常常可以使用最简单的数据结构——数组来更好地表述。 封装复杂结构。当需要非常复杂的数据结构时,使用抽象术语进行定义,并将操作表示为类。 尽可能使用高级工具。超文本、名字—值对、电子表格、数据库、变成语言等都是特定问题领域中的强大的工具 从数据得出程序的结构。通过恰当的数据结构来替代复杂的代码,从数据可以可以得到程序的结构。万变不离其宗:在动手编写代码之前,优秀的程序员会彻底理解输入、输出和中间数据结构,并围绕这些结构创建程序。 编写正确的程序 问题很重要,需要认真地编写代码

编程珠玑:位图法排序

眉间皱痕 提交于 2020-01-26 18:54:42
问题描述 输入:一个最多包含n个正整数的文件,每个数都小于n,其中n=10 7 。如果在输入文件中有任何正数重复出现就是致命错误。没有其他数据与该正数相关联。 输出:按升序排列的输入正数的列表。 约束:最多有1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化。 程序设计与实现概要: 应用位图或位向量表示集合。可用一个10位长的字符串来表示一个所有元素都小于10的简单的非负整数集合,例如,可以用如下字符串表示集合{1,2,4,5,8}: 0 1 1 1 0 1 0 0 1 0 0 代表集合中数值的位都置为1,其他左所有的位置为0.编程珠玑当中建议是一年个一个具有1000万个位的字符串来表示这个文件,那么这个文件的所占容量为10000000 bit=10 7 bit,不到1MB的大小,其中,当且精当整数i在文件中存在,第i为1,这个表示利用了该问题的三个在排序问题中不常见的属性:输入数据限制在相对较小的范围内;数据没有重复;而且对于每条记录而言,除了单一个整数外没有其他关联数据。 如给定表示文件中整数集合的位图数据结构,则可以分三个阶段来编写程序 第一阶段:将所有的位都置为0,从而将集合初始化为空。 第二阶段:通过读入文件中的每个整数来建立集合,将每个对应的位置都置为1。 第三阶段:检验每一位,如果该为为1,就输出对应的整数

算法------编程珠玑(ProgrammingPeals)第三章习题(JAVA)

匿名 (未验证) 提交于 2019-12-02 21:53:52
package code_03_chapter; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /* *Created by William on 2018/6/18 0018 */ public class QuestionsInChapter3 { /** * Q1: * 本书行将出版之时,美国的个人所得税分为5种不同的费率,其中最大的费率大约为40%。 * 以前的情况更为复杂,税率也更高。下面所示的程序文本采用25个if语句的合理方式来计算1978年的美国联邦所得税。 * 税率分别为0.14,0.15,0.16, 0.17, 0.18,・・・・・。此后的费率增幅大于0.01.有何建议? * 两种解法,Q1_1和Q1_2 * Q1_1是硬代码,很难看懂 * 推荐Q1_2,效率也高 */ public static class Q1_1 { public static double taxPay(double

Linux/C/C++ 不可错过的好书

☆樱花仙子☆ 提交于 2019-11-25 19:58:23
来源:公众号【编程珠玑】 作者:守望先生 ID:shouwangxiansheng 前言 经常有读者让我推荐书籍,这次我就把我私藏的计算机书单分享给你们!不过由于时间匆忙,不会进行更加详细的介绍。 声明 由于每个人的情况不一样,推荐的书并不一定适合你,也不一定适合当前阶段的你,有的书籍可能存在内容重复,所以根据自己的阶段情况进行选择即可。虽说如此,以下书单中提单的书均为优质书籍。 另外说,本人从事的是Linux/C/C++应用开发相关工作,因此主要书籍与此相关,涉及操作系统,Linux,C/C++,网络,编译链接,算法,数据库等内容,其他方向的会提到,但可能不全,欢迎补充。 以下整理均来自公众号【编程珠玑】 作者:守望先生 C 《C程序设计语言》(经典,不适合小白入门) 《C语言程序设计:现代方法》 《C primer plus》(入门推荐) 《C陷阱和缺陷》 《C专家编程》 《C和指针》(领悟指针精髓) 《C语言接口与实现》 《C11标准文档》(非书,可查阅) 推荐文 C语言必读 C++ 《 C++ primer》(适合有一定基础) 《C++程序设计语言》 《C++标准库》 《Effective Modern C++ 》 《more effective C++》 《深度探索C++对象模型》 《STL源码剖析》 《effective STL》 《C++ template》