栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用一组质数以升序生成整数

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用一组质数以升序生成整数

基本思想是1是集合的成员,对于集合 n的 每个成员,2 n 和5 n
也是集合的成员。因此,您首先输出1,然后将2和5推入优先级队列。然后,您反复弹出优先级队列的前一项,如果它与先前的输出不同,则将其输出,然后将该数字按2倍和5倍推入优先级队列。

对于“ Hamming Number”或“ Regular
number”,请使用Google或访问A003592以了解更多信息。

-----之后添加-----

我决定在午餐时间花费几分钟来编写一个使用Scheme编程语言实现上述算法的程序。首先,这是使用配对堆算法的优先级队列的库实现:

(define pq-empty '())(define pq-empty? null?)(define (pq-first pq)  (if (null? pq)      (error 'pq-first "can't extract minimum from null queue")      (car pq)))(define (pq-merge lt? p1 p2)  (cond ((null? p1) p2)        ((null? p2) p1)        ((lt? (car p2) (car p1))          (cons (car p2) (cons p1 (cdr p2))))        (else (cons (car p1) (cons p2 (cdr p1))))))(define (pq-insert lt? x pq)  (pq-merge lt? (list x) pq))(define (pq-merge-pairs lt? ps)  (cond ((null? ps) '())        ((null? (cdr ps)) (car ps))        (else (pq-merge lt? (pq-merge lt? (car ps) (cadr ps))      (pq-merge-pairs lt? (cddr ps))))))(define (pq-rest lt? pq)  (if (null? pq)      (error 'pq-rest "can't delete minimum from null queue")      (pq-merge-pairs lt? (cdr pq))))

现在介绍算法。函数

f
采用两个参数,即一组 ps 中的数字列表以及要从输出的开头输出的项数 n
。算法略有变化;通过按1初始化优先级队列,然后开始提取步骤。变量 p 是前一个输出值(最初为0), pq 是优先级队列,而 xs
是输出列表,其输出顺序相反。这是代码:

(define (f ps n)  (let loop ((n n) (p 0) (pq (pq-insert < 1 pq-empty)) (xs (list)))    (cond ((zero? n) (reverse xs))          ((= (pq-first pq) p) (loop n p (pq-rest < pq) xs))          (else (loop (- n 1) (pq-first pq) (update < pq ps)(cons (pq-first pq) xs))))))

对于那些不熟悉Scheme的人来说,

loop
是一个局部定义的函数,它被递归调用,并且
cond
是if-
else链的头。在这种情况下,有三个
cond
子句,每个子句都有一个谓词和一个结果谓词,因此对谓词为true的第一个子句求值。谓词
(zero?n)
终止递归并以正确的顺序返回输出列表。该谓词
(= (pq-first pq)p)
指示优先级队列的当前头先前已输出,因此通过在第一项之后重复优先级队列的其余部分来跳过它。最后,
else

谓词(始终为true)标识要输出的新数字,因此它将递减计数器,将优先级队列的当前头保存为新的先前值,更新优先级队列以添加当前数字的新子项,并且将优先级队列的当前头插入累加输出中。

由于更新优先级队列以添加当前编号的新子代并非易事,因此将该操作提取到单独的函数中:

(define (update lt? pq ps)  (let loop ((ps ps) (pq pq))    (if (null? ps) (pq-rest lt? pq)      (loop (cdr ps) (pq-insert lt? (* (pq-first pq) (car ps)) pq)))))

函数遍历集合中的元素,

ps
依次将每个元素插入优先级队列。在
if
返回更新后的优先级队列,减去其老脸,当
ps
名单被耗尽。递归步骤使用剥离
ps
列表
cdr
的头部,并将优先级队列的头部和
ps
列表的头部的乘积插入优先级队列。

这是该算法的两个示例:

> (f '(2 5) 20)(1 2 4 5 8 10 16 20 25 32 40 50 64 80 100 125 128 160 200 250)> (f '(2 3 5) 20)(1 2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 27 30 32 36)

您可以在http://ideone.com/sA1nn上运行该程序。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/617067.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号