python - 如何在给定素数但指数未知的情况下生成数字?

标签 python math primes factorization hamming-numbers

<分区>

Possible Duplicates:
nth ugly number
Find the Kth least number for expression (2^x)*(3^y)*(5^z)

我想知道如何以快速而优雅的方式解决这个问题:

We define "ugly" every number n which can be written in the form: 2^x * 3^y * 5^z;, where x,y and z are natural numbers. Find the 1500th ugly number.

例如第一个“丑陋”的数字是:

1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, ...

我试过用蛮力解决这个问题,方法是这样的:

import itertools as it

def is_ugly(n):
    '''Return `True` if *n* is an ugly number.'''

    if n == 1:
        return True
    while not n % 2:
        n //= 2
    while not n % 3:
        n //= 3
    while not n % 5:
        n //= 5
    return n == 1

def nth_ugly(n):
    '''Return the nth ugly number.'''

    num = 0
    for i in it.count(1):
        if is_ugly(i):
            num += 1
            if num == n:
                return i

但这需要相当多的时间,我想找到一个更快更好的解决方案。

我知道丑数的素因数,但我想不出一种方法来按照正确的顺序生成这些数字。

我认为必须有一种方法可以生成这些数字而不必检查所有数字。问题是质因子的指数似乎是随机分布的。

看这张表:

n   |number| x | y | z |
------------------------
1   |  1   | 0 | 0 | 0 |
------------------------
2   |  2   | 1 | 0 | 0 |
------------------------
3   |  3   | 0 | 1 | 0 |
------------------------
4   |  4   | 2 | 0 | 0 |
------------------------
5   |  5   | 0 | 0 | 1 |
------------------------
6   |  6   | 1 | 1 | 0 |
------------------------
7   |  8   | 3 | 0 | 0 |
------------------------
8   |  9   | 0 | 2 | 0 |
------------------------
9   |  10  | 1 | 0 | 1 |
------------------------
10  |  12  | 2 | 1 | 0 |
------------------------
11  |  15  | 0 | 1 | 1 |
------------------------
12  |  16  | 4 | 0 | 0 |
------------------------
13  |  18  | 1 | 2 | 0 |
------------------------
14  |  20  | 2 | 0 | 1 |
------------------------
15  |  24  | 3 | 1 | 0 |
------------------------

如您所见,x、y 和 z 值似乎不遵循任何规则。

你们中有人能找到解决这个问题的方法吗?

我正在考虑尝试将问题分成不同的部分。 由于问题是由指数的随机性决定的,我可以尝试独立生成 2s、3s、5s 的幂,然后生成 2^x*3^y、2^x*5^z 等形式的数字。 最后把它们放在一起,但我不知道这是否能解决我的问题。

最佳答案

这是一个完整的解决方案。 O(n) 复杂度,它按顺序生成每个数字一次。

# http://www.cs.utexas.edu/users/EWD/ewd07xx/EWD792.PDF

n = 15
bases = [2, 3, 5]

nums = [1] * n
candidates_indexes = [0 for _ in bases]
candidates = [base for base in bases]

for i in range(1, n):
    nextn = min(candidates)
    nums[i] = nextn

    for index, val in enumerate(candidates):
        if val == nextn:
            candidates_indexes[index] += 1
            candidates[index] = bases[index] * nums[candidates_indexes[index]]

print(nums)

关于python - 如何在给定素数但指数未知的情况下生成数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7333657/

相关文章:

math - 使用两个经度/纬度点获取方向(罗盘)

python - 构造函数未能接受输入参数

python - 如何为 Django 模型实例创建非数据库自动属性

c - C 中的素数生成器

java - 我无法理解 PhotoView 的 getDisplayRect() 实际返回的内容(构建 android 照片裁剪工具)

algorithm - 有效地计算范围内的奇数

python - 从其上三角初始化一个对称的 Theano dmatrix

python popen sdtout在exe失败时没有得到所有输出

python - 素数和斐波那契数列

java - 如何检查 10 位数字是否为质数?