簡體   English   中英

數字減少的最小數字

[英]Smallest number whose digits are decreasing

我發現了一個實現函數的問題,該函數接受一個正整數n作為輸入並返回大於n的最小正整數,該正整數的位數在減小,而對於返回大於n的最小正整數的函數,其正整數又遞增。 我認為增加功能可以正常工作。 但是函數減少有什么錯誤呢? 對於減少的輸入(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))

您需要刪除在遞歸調用中完成的int類型轉換,因為int('00')將您的數字轉換為零(基本上刪除了所有開頭的零)並縮短了字符串的長度。 只需刪除該轉換即可。.其余代碼工作正常:

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)

有多個相互交織的問題需要解決。 這兩個功能的命名令人困惑。 如果我們遵循邏輯,則函數increasing()應稱為nondecreasing() ,類似地,函數decreasing()應稱為nonincreasing() >(大於)和> =(大於或等於)之間的區別。

下一個困惑是這些函數接受返回哪種類型? 如果我們檢查工作中的 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:])))

如果我們類似地查看increasing()如何處理其自身的內部遞歸調用,以查看其認為接受和返回的內容,則會得到:

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

因此,這里嘗試了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))))

decreasing() aka nonincreasing()函數的問題更大。 它依靠接受int或內部調用的str來解決問題的能力。

討論這些問題,而不是讓其他程序員重新發現它們,是代碼注釋的全部內容。

我不認為上述問題會阻止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)

修復此功能的關鍵是從倒數第二個if子句中刪除return語句,而是修復數據,然后讓它進入下一個if子句,以查看結果是否需要修復。

我相信@ devender22對int()強制轉換的見解是至關重要的,但是我不認為隨附的解決方案是有效的,因為它會生成大量錯誤結果(例如,從990到998到1000時它們都應該被簡單地撞掉) 1)。

為了檢查我的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

然后確保兩個實現在其輸出上達成一致。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM