简体   繁体   English

数字减少的最小数字

[英]Smallest number whose digits are decreasing

I found a problem to implement functions that takes a positive integer n as an input and returns the smallest positive integer larger than n whose digits are decreasing and similarly for a function that returns the smallest positive integer larger than n whose digits are increasing. 我发现了一个实现函数的问题,该函数接受一个正整数n作为输入并返回大于n的最小正整数,该正整数的位数在减小,而对于返回大于n的最小正整数的函数,其正整数又递增。 I think the increasing function works correctly. 我认为增加功能可以正常工作。 But what is the mistake in the function decrease? 但是函数减少有什么错误呢? For the input decreasing(100) it returns 11 rather than 110. 对于减少的输入(100),它返回11而不是110。

# the next integer whose digits are increasing.
def increasing(n):
    asastring = str(n)
    length = len(asastring)
    if asastring == "9"*length:
        return "1"*(length+1)
    if length == 1:
        return int(n)+1

    if length >= 2:
        firstcharacter = asastring[0]
        secondcharacter = asastring[1]
        if int(firstcharacter) > int(secondcharacter):
            return int(str(firstcharacter)*length)
        if firstcharacter == secondcharacter:
             return firstcharacter+str(increasing(int(asastring[1:])))
        if int(firstcharacter) < int(secondcharacter):
            if secondcharacter == "9":
                return str(int(firstcharacter)+1) * len(str(n))
            return firstcharacter+str(increasing(int(asastring[1:])))

# the next integer whose digits are decreasing.
def decreasing(n):
    asastring = str(n)
    length = len(asastring)
# First the case where we need to add a digit.
    if asastring == "9"*length:
        return "1"+"0"*length
# Now we know that the next integer has the same number of digits as the original number.
    if length == 1:
        return int(n)+1
    if length >= 2:
        firstcharacter = asastring[0]
        secondcharacter = asastring[1]
        if int(firstcharacter) > int(secondcharacter):
            endpart = str(((asastring[1:3])))
            value = firstcharacter + str(decreasing(int(asastring[1:])))
            return str(firstcharacter) + str(decreasing(int(asastring[1:])))
        if int(firstcharacter) == int(secondcharacter):
            return decreasing(firstcharacter+str(decreasing(int(asastring[1:]))))
        if int(firstcharacter) < int(secondcharacter):
            return str(int(firstcharacter)+1)+'0'*(length-1)

i=100
print(increasing(i))
print(decreasing(i))

You need to remove the int type casting done in the recursive calls as int('00') is converting your number to zero(basically removing all starting zeros) and shortening the length of your string. 您需要删除在递归调用中完成的int类型转换,因为int('00')将您的数字转换为零(基本上删除了所有开头的零)并缩短了字符串的长度。 Just remove that casting.. remaining code is working fine: 只需删除该转换即可。.其余代码工作正常:

def decreasing(n):
    asastring = str(n)
    length = len(asastring)
# First the case where we need to add a digit.
    if asastring == "9"*length:
        return "1"+"0"*length
# Now we know that the next integer has the same number of digits as the original number.
    if length == 1:
        return int(n)+1
    if length >= 2:
        firstcharacter = asastring[0]
        secondcharacter = asastring[1]
        if int(firstcharacter) > int(secondcharacter):
            return str(firstcharacter) + str(decreasing(asastring[1:]))
        if int(firstcharacter) == int(secondcharacter):
            return decreasing(firstcharacter+str(decreasing(asastring[1:])))
        if int(firstcharacter) < int(secondcharacter):
            return str(int(firstcharacter)+1)+'0'*(length-1)

There are multiple intertwined issues that need to be addressed. 有多个相互交织的问题需要解决。 The naming of these two functions is a source of confusion. 这两个功能的命名令人困惑。 If we follow the logic, then the function increasing() should be called nondecreasing() and similarly, the function decreasing() should be called nonincreasing() . 如果我们遵循逻辑,则函数increasing()应称为nondecreasing() ,类似地,函数decreasing()应称为nonincreasing() It's the difference between > (greater than) and >= (greater than or equal). >(大于)和> =(大于或等于)之间的区别。

The next confusion is what type do these functions accept and return ? 下一个困惑是这些函数接受返回哪种类型? If we examine what the working increasing() function returns, we get: 如果我们检查工作中的 increasing()函数返回的内容,则会得到:

str return "1"*(length+1)
int return int(n)+1
int return int(str(firstcharacter)*length)
str return firstcharacter+str(increasing(int(asastring[1:])))
str return str(int(firstcharacter)+1) * len(str(n))
str return firstcharacter+str(increasing(int(asastring[1:])))

If we similarly look at how the increasing() deals with its own internal recursive calls to see what it thinks it accepts and returns, we get: 如果我们类似地查看increasing()如何处理其自身的内部递归调用,以查看其认为接受和返回的内容,则会得到:

int -> int  return firstcharacter+str(increasing(int(asastring[1:])))
int -> int  return firstcharacter+str(increasing(int(asastring[1:])))

So here's an attempted rework of increasing() , aka nondecreasing() , that tries to make it consistently accept an int and return an int : 因此,这里尝试了increasing() ,又称为nondecreasing()重做,试图使其始终接受一个int并返回一个int

def nondecreasing(n):  # aka increasing()
    as_string = str(n)
    length = len(as_string)

    if as_string == "9" * length:
        return int("1" * (length + 1))

    if length == 1:
        return int(n) + 1

    first_digit, second_digit, second_digit_onward = as_string[0], as_string[1], as_string[1:]

    if first_digit > second_digit:
        return int(first_digit * length)

    if first_digit == second_digit:
        return int(first_digit + str(nondecreasing(int(second_digit_onward))))

    if as_string == first_digit + "9" * (length - 1):
        return int(str(int(first_digit) + 1) * length)

    return int(first_digit + str(nondecreasing(int(second_digit_onward))))

The decreasing() , aka nonincreasing() , function is more problematic. decreasing() aka nonincreasing()函数的问题更大。 It relies on its ability to accept an int , or a str upon internal calls, to solve the problem. 它依靠接受int或内部调用的str来解决问题的能力。

Discussing these sort of issues, and not making other programmers rediscover them, are what code comments are all about. 讨论这些问题,而不是让其他程序员重新发现它们,是代码注释的全部内容。

I don't believe the above issue precludes nonincreasing() from consistently returning an int : 我不认为上述问题会阻止nonincreasing()始终返回 int

def nonincreasing(n):  # aka decreasing()
    as_string = str(n)
    length = len(as_string)

    if as_string == "9" * length:
        return int("1" + "0" * length)

    if length == 1:
        return int(n) + 1

    first_digit, second_digit, second_digit_onward = as_string[0], as_string[1], as_string[1:]

    if first_digit > second_digit:
        return int(first_digit + str(nonincreasing(second_digit_onward)))

    if first_digit == second_digit:
        remaining_digits = str(nonincreasing(second_digit_onward))
        second_digit = remaining_digits[0]
        n = first_digit + remaining_digits

    if first_digit < second_digit:
        return int(str(int(first_digit) + 1) + '0' * (length - 1))

    return int(n)

The key to fixing this function was to remove the return statement from the penultimate if clause and instead fix up the data and let it fall through to the next if clause to see if the results need repair or not. 修复此功能的关键是从倒数第二个if子句中删除return语句,而是修复数据,然后让它进入下一个if子句,以查看结果是否需要修复。

I believe @devender22's insight about int() casting is a crucial one but I don't believe the accompanying solution is valid as it generates large blocks of incorrect results (eg 990 through 998 all go to 1000 when they should simply be bumped up by 1). 我相信@ devender22对int()强制转换的见解是至关重要的,但是我不认为随附的解决方案是有效的,因为它会生成大量错误结果(例如,从990到998到1000时它们都应该被简单地撞掉) 1)。

In order to check my nonincreasing() function with all of its cases, I wrote a less efficient, non-recursive solution, without separate cases, using completely different Python operators: 为了检查我的nonincreasing()函数的所有情况,我使用完全不同的Python运算符编写了一个效率较低,非递归的解决方案,没有单独的情况:

def nonincreasing(n):

    def is_increasing(n):
        string = str(n)

        return any(map(lambda x, y: y > x, string, string[1:]))

    while is_increasing(n + 1):
        n += 1

    return n + 1

And then made sure the two implementations agreed on their output. 然后确保两个实现在其输出上达成一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何找到最小的四位数字,其数字不重复,但加起来是一个随机数 - How to find the smallest four digit number, whose digits dont repeat, but add up to a randomized number 查找下一个具有相同数字的最小数字 Python - FInd Next smallest number with same digits Python 从其他数字的最小数字创建数字 - Creating a number from smallest digits of other numbers 如何找到不能被 3 整除的最小 n 位数? - How can I find the smallest number of n digits that is not divisible by 3? 创建一个函数,从其输入参数的数字中生成最小数字 - Create a function that makes a smallest number from the digits of its input parameter 前 n 位可被 n 整除的 10 位数字 - 10 digit number whose first n digits are divisible by n 生成数字严格递减的数字 - Generate numbers with strictly decreasing digits 寻找最小数字中的数字阶乘总和 == 给定数字时的奇怪输出 - Weird output when looking for sum of factorial of digits in smallest number == the given number 查找由数字组成的 N 位数字的计数,总和等于 K。返回计数,最小和最大数字 - Find count of N-digits numbers which consist of digits give you the sum is equal to K. Return count, the smallest and the largest number 总和超过阈值的最小区间 - Smallest interval whose sum exceeds a threshold
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM