生成数字严格递减的数字

2024-06-25 23:51:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图生成最大长度为n的数字,其所有数字都严格递减

如果‍‍n = 5‍, 那么数字将是:

54321
5432
543
54
5421
542
541
5321
532
53
521
52
51
5
4321
432
43
431
421
42
41
4
...

有关于如何进行的提示吗

先谢谢你

编辑- 我当前的代码是这样的,我没有得到所有的结果

def func(arr):
for x in arr:
    token=x[-1]
    k=int(token)-1
    while k>1:
        for i in range(1,k):
            f.write(x)
            for j in range(k,i,-1):
                f.write(str(j))
        k-=1

f = open ("demo.txt", "w")

arr = ["987"]
for i in range(986,321,-1):
    tens = i
    units = i%10
    tens = int(tens)/10
    hundreds = int(tens)/10 
    tens%=10
    hundreds%=10
    if tens >= hundreds or units>= tens:
        continue
    arr.append(str(i))

func(arr)
f.close()

Tags: 代码intoken编辑forrange数字write
3条回答

下面是一个递归生成器函数:

def nums(n):
    if n:
        yield from (int(f"{n}{num}") for num in nums(n-1))
        yield n
        yield from nums(n-1)
       

[*nums(1)]
# [1]
[*nums(2)]
# [21, 2, 1]
[*nums(3)]
# [321, 32, 31, 3, 21, 2, 1]
[*nums(4)]
# [4321, 432, 431, 43, 421, 42, 41, 4, 321, 32, 31, 3, 21, 2, 1]

或者使用^{}方法:

from itertools import combinations

def nums(n):
    for l in range(n, 0, -1):
        for c in combinations(range(n, 0, -1), l):
            yield int("".join(map(str, c)))

[*nums(2)]
# [21, 2, 1]
[*nums(3)]
# [321, 32, 31, 21, 3, 2, 1]
[*nums(4)]
# [4321, 432, 431, 421, 321, 43, 42, 41, 32, 31, 21, 4, 3, 2, 1]

它实际上并不复杂,您可以使用itertools.combinations生成数字组合,然后使用zip应用一个因子,并获取每个项目和sum的乘积

例如,系数为[1,101001000]的[1,2,4,5]将给出1+20+400+5000=5421

诀窍在于combinations总是以定义的顺序(从早到晚)生成组合,因此combinations([1,2,3], 2)将给出[(1, 2), (1, 3), (2, 3)]

from math import prod
n = 5
factors = [10**i for i in range(n)]
[sum(map(prod, zip(factors, c)))
 for i in range(n,0,-1)
 for c in combinations(range(1,n+1), i)]

输出:

[54321,
 4321,
 5321,
 5421,
 5431,
 5432,
 321,
 421,
 521,
 431,
 531,
 541,
 432,
 532,
 542,
 543,
 21,
 31,
 41,
 51,
 32,
 42,
 52,
 43,
 53,
 54,
 1,
 2,
 3,
 4,
 5]

如果需要严格的输出顺序,请使用以下方法(效率稍低):

[sum(map(prod, zip(factors, c)))
 for i in range(n,0,-1)
 for c in list(combinations(range(1,n+1), i))[::-1]]

输出:

[54321,
 5432,
 5431,
 5421,
 5321,
 4321,
 543,
 542,
 532,
 432,
 541,
 531,
 431,
 521,
 421,
 321,
 54,
 53,
 43,
 52,
 42,
 32,
 51,
 41,
 31,
 21,
 5,
 4,
 3,
 2,
 1]

all digits are strictly decreasing.

此代码生成具有自定义长度的降序数字序列:

import itertools


def generate(lenght):
    arr = [range(10)] * lenght
    for digits_tuple in itertools.product(*arr):
        if all(current_item > next_item for current_item, next_item in zip(digits_tuple, digits_tuple[1:])):
            print(digits_tuple)


generate(5)

如果希望长度小于等于5,请执行以下操作:

for i in range(5):
   generate(i+1)

问题有点模糊,但您可以更改这部分代码以实现您的目标:

all(current_item > next_item for current_item, next_item in zip(digits_tuple, digits_tuple[1:])):

相关问题 更多 >