16场比赛

2013年10月29日

当地一家商店有一个促销游戏,其中刮擦卡片有16个空格,覆盖数字1到16的随机排列。客户随意划掉空间。如果刮擦显示数字3,则卡片丢失。如果刮擦显示数字1和2,以任意顺序,则该卡获胜。中奖的卡片可以在商店商品上获得折扣。

你的任务是编写一个程序来确定平均获胜百分比。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

悲观算法与简单性分析

2013年10月25日

我一直在读书悲观算法与简单性分析 安德烈·布罗德和豪尔赫·斯托尔菲。这很有趣。他们编写了三个程序:搜索排序数组中的项,枚举连接图中的所有项,并将数组按升序排序;我们将查看排序算法,但您可能需要自己查看其他算法。下面是他们的排序算法:

这个慢速排序算法是对乘法投降范式,这可能是不情愿算法开发中最重要的一个范式。基本的乘法和放弃策略是将手头的问题替换为两个或多个子问题,每个子问题都比原始问题略简单,并尽可能长时间地以这种方式递归地乘法子问题和子问题。在某些时候,子问题将变得如此简单,以至于它们的解决方案无法再推迟,我们将不得不放弃。经验表明,在大多数情况下,当达到这一点时,总工作量将大大高于采用更直接的方法所浪费的工作量。

为了更好地掌握乘法和投降法,让我们循序渐进地学习慢速排序算法。我们可以分解排序问题n个数字A,A2,…,An个按升序排列为:(1)找出这些数字中的最大值,(2)对其余的数字进行排序。子问题(1)可以进一步分解为(1.1)f和第一个问题的最大值[n个/2] 元素,(1.2)f和其余元素的最大值[n个/2] 元素,以及(1.3)f这两个最大值中的最大值。最后,子问题(1.1)和(1.2)可以通过对指定元素进行排序并取结果中的最后一个元素来解决。因此,我们将原来的问题倍增为三个稍微简单的问题(对前半部分进行排序,对后半部分进行分类,对除一个以外的所有元素进行排序),再加上一些开销处理。我们继续递归地这样做,直到列表中每个最多有一个元素,此时我们被迫放弃。

我没有抄袭文章中的代码;如果你去看它,当心虫子!该算法的时间复杂度为O(n个日志2(n个)/2).

您的任务是编写慢速排序程序;您可能还想编写研究bwfs(磅/英尺)文章中提到的程序。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布解决方案或讨论练习。

页:1 2

David Gries的咖啡罐问题

2013年10月22日

David Gries在他1981年的书中描述了今天的练习程序设计科学; 我是从乔恩·本特利2000年的书中学到的编程珠玑,第二版。

最初你会得到一个咖啡罐,里面有一些黑豆和一些白豆,还有一大堆“多余的”黑豆。然后重复以下过程,直到罐中只剩下一个bean。

从罐头中随机选择两颗豆子。如果它们是相同的颜色,把它们都扔掉,再加一个黑豆。如果它们是不同的颜色,把白豆放回罐子里,把黑豆扔掉。

证明进程终止。你能说最后剩下的豆子的颜色是最初在罐子里的黑豆和白豆数量的函数吗?

你的任务是回答上述两个问题,然后编写一个模拟咖啡罐问题的程序。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

二叉树遍历

2013年10月18日

在一个上一次练习,我们编写了一个用于维护二进制搜索树的小库,其中包括一个按顺序遍历树的函数。在今天的练习中,我们将编写按前序和后序遍历树的函数。

给定右侧显示的树,预先排序的遍历按以下顺序访问节点:8 3 1 6 4 7 10 14 13。在树的每个级别上,预排序遍历首先处理当前节点,然后在左侧子级递归调用自身,然后在右侧子级递归地调用自身。

后序遍历按以下顺序访问节点:1 4 7 6 3 13 14 10 8。在树的每个级别上,后序遍历在左子级递归调用自身,然后在右子级递归地调用自身,最后处理当前节点。

除了按前序或后序遍历树之外,还应该编写函数,在给定按前序和后序排列的树节点列表的情况下,重建原始树。

您的任务是编写上述四个函数。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

查找最小差异

2013年10月15日

今天,我们将从无限的面试问题中进行另一项练习:

给您两个整数数组,其中整数不重复,两个数组没有公共整数,并且两个数组都按升序排序。

x个为第一个数组中的任意整数,并且可以是第二个数组中的任何整数。查找最小值(abs(x个)); 即,找出两个数组中任意整数之间的最小差值。

你的任务是编写一个程序来找出最小的差异。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

强制样式链接列表

2013年10月11日

上一次练习我们实现了函数式链表的一些基本操作;它们的显著特点是组成列表的对是不可变的。在今天的练习中,我们将实现命令式链接列表,其中组成列表的对是可变的。

您的任务是编写相同的函数库-为零一对第n个长度追加、和颠倒-用于命令式可变链表,正如您在上一个练习中为函数式不可变链表所写的那样。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

功能样式链接列表

2013年10月8日

我们经常在程序中使用链接列表,但Scheme使这一点变得简单,因为它将链接列表作为本机数据类型提供,并对其进行丰富的操作。在今天的练习中,我们将以Scheme本机提供的功能样式实现列表。

在Scheme中,列表实际上只不过是一个具有两个插槽的数组,即car和cdr对;没有元素的列表称为空列表。我们经常认为列表是一系列元素,但实际上列表只不过是一个对链,其中每对的cdr是另一个列表,链以空列表结尾。根据您使用的Scheme版本,这对车和cdr可能可变,也可能不可变;传统上,它们是可变的,但最新批准的标准R6RS使配对不可变(这是有争议的,Scheme的许多实现忽略了它,并使配对可变)。尽管如此,不可变对与函数式语言的精神更紧密地结合在一起,您现在的实现应该提供不可变对。

您的任务是实现一个小型列表运算符库;你应该至少包括nil和一个识别它的谓词,一个构建对的过程和两个提取对片段的过程,提取列表第n项并确定其长度的函数,以及反转列表元素并附加两个列表的函数;如果您愿意,欢迎您提供更多操作员。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

正在计算统计信息

2013年10月4日

在今天的练习中,我们将做某人的作业:

读取包含整数的文件,每行一个整数。在文件的末尾,写下文件中的整数数量、它们的总和以及文件中整数的平均值、中值、模式、最小值和最大值。

你的任务是编写指定的程序。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2

卢卡斯序列

2013年10月1日

我们在之前的练习中研究了斐波那契数。在今天的练习中,我们将学习一种称为卢卡斯数的斐波那契数的泛化,这是由Edouard Lucas在19世纪末研究的。

回想一下,每个斐波那契数都是前两个斐波那奇数的和,前两个是1和1;因此,斐波那契数列的开头是1、1、2、3、5、8、13、21、34、55…。卢卡斯数的定义是相似的,但前两个卢卡斯数是1和3;因此,卢卡斯数从1、3、4、7、11、18、29、47、76……开始,它们的增长速度比斐波那契数更快。

卢卡斯进一步推广了斐波那契数。他定义了两个序列U型n个(P(P))和V(V)n个(P(P))如下:以整数开头P(P)令人满意的D类=P(P)2− 4> 0. 然后,根据二次公式x个2价格x+=0是= (P(P)+平方英尺(D类))/2和b条= (P(P)−平方米(D类)) / 2. 然后U型n个(第页q个) = (n个n个) / (b条)和V(V)n个(P(P)) =n个+n个.

现在斐波那契数和卢卡斯数只是U型V(V)序列:斐波那契数列为U型n个(1,-1)和卢卡斯数字是V(V)n个(1, -1).

很容易计算特定的U型V(V)顺序。这些公式类似于计算斐波那契数列的方法:U型(P(P)) =公共事业部−1(P(P)) −问U−2(P(P))和V(V)(P(P)) =P V(预测值)−1(P(P)) −Q V型−2(P(P)).

计算特定的U型V(V)在序列中,使用基于以下恒等式的仅需要对数时间的链:U型2n个=U型n个U型n个U型2n个+1=U型n个+1 V(V)n个n个V(V)2n个=V(V)n个2− 2n个、和V(V)2n个+1=V(V)n个+1 V(V)n个P Q公司n个.

您可以在上查看所有这些公式数学世界我们对卢卡斯序列的兴趣不仅仅是学术上的;我们将在未来的练习中看到Lucas序列的应用。

您的任务是编写计算U型V(V)序列,并计算两个序列中任意一个的给定元素。完成后,欢迎您阅读运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习。

页:1 2