Math 从有序的指数序列生成项
我正在为下面的问题写一个解决方案 A是包含所有元素2^I*3^Q的列表,其中I和Q是升序的整数 编写一个函数f,以便: f(N)返回A[N] 前几个要素是: A[0]=1 A[1]=2 A[2]=3 A[3]=4 A[4]=6 A[5]=8 A[6]=9 A[7]=12 我的解决方案是通过15次双循环生成包含前225个元素的列表,然后对该列表进行排序并返回[N]Math 从有序的指数序列生成项,math,sequences,Math,Sequences,我正在为下面的问题写一个解决方案 A是包含所有元素2^I*3^Q的列表,其中I和Q是升序的整数 编写一个函数f,以便: f(N)返回A[N] 前几个要素是: A[0]=1 A[1]=2 A[2]=3 A[3]=4 A[4]=6 A[5]=8 A[6]=9 A[7]=12 我的解决方案是通过15次双循环生成包含前225个元素的列表,然后对该列表进行排序并返回[N] 有没有办法在不首先创建和排序列表的情况下生成此序列的第N个元素?这里有两种方法可以在不创建如此大的列表的情况下解决您的问题。每种方法都
有没有办法在不首先创建和排序列表的情况下生成此序列的第N个元素?这里有两种方法可以在不创建如此大的列表的情况下解决您的问题。每种方法都有其缺点 首先,您可以将计数器设置为0。然后扫描从1开始的所有整数。对于每个整数,在其因式分解中,将2和3的所有倍数除掉。如果仍为1,则递增计数器;否则,保持计数器不变。当计数器达到
N
时,您已找到A[N]
的值。例如,增加整数1、2、3和4的计数器,但不增加5的计数器。这种方法使用很少的内存,但会花费很多时间
second方法使用最小优先级队列,如Python的heapq
。同样,将计数器设置为零,但同时初始化优先级队列以仅保留数字1,并注意到目前为止看到的3的最高幂也是1。增加计数器,然后查看队列中的最小数量。如果计数器为N
,则只得到A[N]
的值。否则,弹出该最小值并立即将其值加倍。(pop和push可以在多个优先级队列中的一次操作中完成。)如果该值是迄今为止看到的最高3次方,也可以推三次其值,请注意,此新值现在是最高3次方
第二种方法使用占用一些内存的优先级队列,但最大大小仅为N
的平方根。我希望时间大致相当于您对大列表进行排序的时间,但我不确定。这种方法有最复杂的代码,需要您有一个最小优先级队列
您的算法的优点是简单,缺点是列表太大。事实上,给定的N
2和3的最大幂并不明显,因此您需要使列表比需要的大得多。例如,您计算“前225个元素通过每个元素15次的双循环”的情况实际上只适用于N=82
下面是所有三种方法的Python代码。使用timeit
进行N=200
我得到了以下计时:
1.19 ms for sorting a long list (your approach) (powerof2=powerof3=30)
8.44 s for factoring increasing integers
88 µs for the min priority queue (maximum size of the queue was 17)
优先级队列以很大的优势获胜——比我预期的要大得多。以下是所有三种方法的Python 3.6.4代码:
"""A is a list containing all elements 2^I * 3^Q where I and Q are
integers in an ascending order. Write a function f such that
f(N) returns A[N].
Do this without actually building the list A.
Based on the question <https://stackoverflow.com/questions/49615681/
generating-an-item-from-an-ordered-sequence-of-exponentials>
"""
import heapq # min priority queue
def ordered_exponential_0(N, powerof2, powerof3):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the questioner's algorithm
"""
A = [2**p2 * 3**p3 for p2 in range(powerof2) for p3 in range(powerof3)]
A.sort()
return A[N]
def ordered_exponential_1(N):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the algorithm of factoring increasing integers.
"""
i = 0
result = 1
while i < N:
result += 1
num = result
while num % 2 == 0:
num //= 2
while num % 3 == 0:
num //= 3
if num == 1:
i += 1
return result
def ordered_exponential_2(N):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the algorithm using a priority queue.
"""
i = 0
powerproducts = [1] # initialize min priority queue to only 1
highestpowerof3 = 1
while i < N:
powerproduct = powerproducts[0] # next product of powers of 2 & 3
heapq.heapreplace(powerproducts, 2 * powerproduct)
if powerproduct == highestpowerof3:
highestpowerof3 *= 3
heapq.heappush(powerproducts, highestpowerof3)
i += 1
return powerproducts[0]
A是一个包含所有元素2^I*3^Q的列表,其中I和Q是
升序整数。写一个函数f,使
f(N)返回一个[N]。
在不实际构建列表A的情况下执行此操作。
基于这个问题
"""
导入heapq#最小优先级队列
def有序指数(N,幂2,幂3):
“”“返回2和3的幂的第n个(从零开始)乘积。
这使用了提问者的算法
"""
A=[2**p2*3**p3表示p2在范围内(powerof2)表示p3在范围内(powerof3)]
A.排序()
返回A[N]
def有序指数_1(N):
“”“返回2和3的幂的第n个(从零开始)乘积。
这使用了递增整数的因式分解算法。
"""
i=0
结果=1
而iN
可以与200
一样大,则原始方法需要更大的列表。要获得N=200
的正确答案,您需要进行从0到23的2次幂和从0到15的3次幂运算。