如何生成仅包含 0 和 9 的数字

Elt*_*dov 2 c++ algorithm loops generator python-3.x

嗨,我想在 python 或 C++ 中生成仅包含 0 和 9 的数字并不重要,我这样写:

for i in range(0,100):
    random_number = 9 * 10**i
    for j in range(0,i):
        second_sum = 9 *10 ** j
        random_number += second_sum
    print(random_number)


Run Code Online (Sandbox Code Playgroud)

但像这样输出

9
99
999
9999
99999
999999
9999999
99999999
999999999
9999999999
............
..............
Run Code Online (Sandbox Code Playgroud)

但预期的输出是

9
90
99
900
909
990
999
9000
9009
9090
9099
9900
9990
9999
--snip--
Run Code Online (Sandbox Code Playgroud)

任何人都请帮助我:)

And*_*ely 7

根据@B.Go 的评论,这是替换这些的解决方案:

def generate(n=5):
    for i in range(1, 2**n):
        yield int('{:b}'.format(i).replace('1', '9'))

print([*generate(5)])
Run Code Online (Sandbox Code Playgroud)

印刷:

[9, 90, 99, 900, 909, 990, 999, 9000, 9009, 9090, 9099, 9900, 9909, 9990, 9999, 90000, 90009, 90090, 90099, 90900, 90909, 90990, 90999, 99000, 99009, 99090, 99099, 99900, 99909, 99990, 99999]
Run Code Online (Sandbox Code Playgroud)

  • 只需乘以 9 即可。 (3认同)

nor*_*ok2 5

(已编辑

你的方法行不通,因为:

  • 您打印的random_number频率不够高。
  • 即使你是,你也不会通过重复产生所有可能的排列。
for i in range(0, 3):
    random_number = 9 * 10 ** i
    print(random_number)  # <--- HERE
    for j in range(0, i):
        second_sum = 9 * 10 ** j
        random_number += second_sum
        print(random_number)  # <--- HERE

# 9
# 90
# 99
# 900
# 909
# 999
Run Code Online (Sandbox Code Playgroud)

990 缺少并且这种方法不容易推广,因为它需要任意数量的嵌套循环。


还有其他几种可能的方法,或者基于itertools.product(作为无限生成器扩展更通用和更简单)或基于观察到自然数的二进制表示非常接近您的目标输出:

import itertools


def my_gen_itertools(max_len=0, items='09'):
    length = 1
    while max_len and length <= max_len:
        for x in itertools.product(items, repeat=length):
            if x[0] != items[0]:
                yield int(''.join(x))
        length += 1


def my_gen_bin_mult(n, factor=9):
    for i in range(1, 2 ** n):
        yield int(bin(i)[2:]) * factor


def my_gen_bin_replace(n, subst='9'):
    for i in range(1, 2 ** n):
        yield int('{:b}'.format(i).replace('1', subst))


def my_gen_bit_mult(n, factor=9):
    k = [10 ** i for i in range(n)]
    for value in range(1, 2 ** n):
        result = 0
        j = 0
        while value:
            result += (value & 1) * k[j]
            value >>= 1
            j += 1
        yield result * factor
Run Code Online (Sandbox Code Playgroud)

请注意,my_gen_bin_replace()实质上是在提出的解决方案@ AndrejKesely的答案,除了是使用了更高效的bin()呼吁得到的二进制表示,两者my_gen_bin_replace()my_gen_bin_mult()都实现提出的方法@ Orace的答案

my_gen_bit_mult()my_gen_bin_mult()此类似,只是在没有中间字符串表示的情况下进行处理,但使用相当昂贵的功率计算和 Python 直接循环,但它最容易转换为 C++(直接循环不会那么慢)。


速度方面,乘以二进制表示似乎是最快的:

funcs = my_gen_itertools, my_gen_bin_mult, my_gen_bin_replace, my_gen_bit_mult
for func in funcs:
    print()
    print(func.__name__)
    print(list(func(4)))
    %timeit list(func(20))

# my_gen_itertools
# [9, 90, 99, 900, 909, 990, 999, 9000, 9009, 9090, 9099, 9900, 9909, 9990, 9999]
# 1 loop, best of 3: 839 ms per loop

# my_gen_bin_mult
# [9, 90, 99, 900, 909, 990, 999, 9000, 9009, 9090, 9099, 9900, 9909, 9990, 9999]
# 1 loop, best of 3: 572 ms per loop

# my_gen_bin_replace
# [9, 90, 99, 900, 909, 990, 999, 9000, 9009, 9090, 9099, 9900, 9909, 9990, 9999]
# 1 loop, best of 3: 739 ms per loop

# my_gen_bit_mult
# [9, 90, 99, 900, 909, 990, 999, 9000, 9009, 9090, 9099, 9900, 9909, 9990, 9999]
# 1 loop, best of 3: 3.97 s per loop
Run Code Online (Sandbox Code Playgroud)