【问题标题】:Checking if a number has any repeated elements检查一个数字是否有任何重复的元素
【发布时间】:2021-08-31 13:33:45
【问题描述】:

我一直致力于将整数拆分为它们所包含的数字,然后检查列表中是否有任何重复的数字。然而,代码似乎总是说没有重复的数字,即使有。

我的代码:

def repeatCheck(myList, repeatedNumber):
    seen = set()
    for number in myList:
        if number in seen:
            repeatedNumber = True
        seen.add(number)
    return repeatedNumber


def numberWorks(number, finalNumber):    
    digits = [int(n) for n in str(number)]
    repeatedNumber = False
    repeatCheck(digits, repeatedNumber)
    if repeatedNumber == False:
        print(number, "succeeded repeatedNumber")
        found = True
    else:
        print(number, "failed repeatedNumber")
        pass
    return number


number = 1000000000

while found == False:
    numberWorks(number, finalNumber)
    number += 1
print(finalNumber)

输入编号为 1000000000,输出应为 1023456789

如果我提供的代码不够用,请告诉我任何可以解决的方法。

谢谢。

【问题讨论】:

  • 你能解释一下conitionedNumber的意义吗?此外,您对范围的使用无处不在,由于底部的缩进,该代码甚至不会运行。您可能应该努力弄清楚 return 语句是如何工作的。
  • 请添加示例输入和预期输出
  • 顺便说一句,看你写的标题,有很多方法可以解决这个问题,但首先给我们一个例子。
  • 在最后一个 while 循环中您需要 == 而不是 =,而在它之后您缺少 :
  • 对不起,我在尝试创建一个最小的可复制代码时犯了这些错误,并在制作时弄乱了其中的一些。我现在已经解决了所有被指出的问题。

标签: python math split integer


【解决方案1】:

当您调用函数repeatCheck() 时,您不会传递对变量repeatedNumber 的引用,因此对变量的任何更改都不会影响repeatedNumber 的原始定义。因此,numberWorks() 中定义的repeatedNumber 永远不会更新。

您可以做的是将repeatCheckreturn 值分配给repeatedNumber

repeatedNumber = False
repeatedNumber = repeatCheck(digits)

并在看到重复时重写 repeatCheck 以返回 TrueFalse

def repeatCheck(myList):
    seen = set()
    for number in myList:
        if number in seen:
            return True
        seen.add(number)
    return False

这样你就可以避免重复使用变量名repeatedNumber的歧义

【讨论】:

  • 谢谢!我将您提供的代码编辑为一行``` if repeatCheck(digits) == False: ``` 并将函数更改为您的操作方式。
  • 是的,这确实是一个很棒的解决方案!
【解决方案2】:

如果您想检查数字中的重复数字,这里有一个返回布尔值的快速方法。

def noRepeatedDigits(number:int) -> bool:
  return all([str(number).count(i) == 1 for i in set(str(number))])

print(noRepeatedDigits(12344))
print(noRepeatedDigits(1234))
False #indicates it failed the check
True #indicates it passed the check

【讨论】:

  • 哇很棒的解决方案。从来没有这样想过我通常会做我回答的事情。但我不得不承认这要好得多!
  • 谢谢,它与其他答案(包括你的)非常相似,它只是利用内置函数来压缩它!
【解决方案3】:

我会简单地删除您的所有代码并执行此操作。

def repeatCheck(repeatedNumber):
    numbersdub = list(str(repeatedNumber))
    numbers = set(numbersdub)
    for num in numbers:
        numbersdub.remove(num)
    return set(numbersdub)


print(repeatCheck(78788))

这会给你一套所有的dubbels。

【讨论】:

  • .remove的复杂度是线性的,也就是说这个函数的整体复杂度是二次的。
  • 您可以使用collections.Counter 而不是list 获得具有线性时间复杂度的所有重复项的集合。 collections.Counter 是多组的理想选择。因此s = str(repeatedNumber); return (collections.Counter(s) - collections.Counter(set(s))).keys() 将是线性的并返回重复项。
  • 当然,以 10 为基数只有 10 个可能的不同数字,所以你几乎可以忽略我以前的 cmets :)
  • 那么我的解决方案是否不好?它不是线性的吗?
  • 您的解决方案是 O(n * m),其中 n 是数字的位数,m 是数字的不同位数。从这个意义上说,它是二次的。但是 m huge 循环中调用他们的函数 repeatCheck(他们正在迭代 10**10 个数字),所以我们可以进行的每一次优化都很重要,也是唯一的方法要知道哪种解决方案最好是使用timeit
【解决方案4】:

替代的单线解决方案:

finalNumber = next(n for n in range(1000000000, 2000000000) if len(set(s := str(n))) == len(s))

print(finalNumber)
# 1023456789

解释:len(str(n))n的位数,而len(set(str(n)))n的唯一位数。仅当 n 没有重复数字时,这两个数量才相等。

整个东西都包裹在一个迭代器中,next( ) 返回迭代器的第一个值。

【讨论】:

    猜你喜欢
    • 2021-05-02
    • 1970-01-01
    • 2016-06-07
    • 2011-05-06
    • 1970-01-01
    • 2012-10-01
    • 2017-12-19
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多