实现算法以确定字符串是否具有所有唯一字符

时间:2013-06-28 04:47:54

标签: python

背景:我是一名CS n00b正在通过“破解编码面试”。第一个问题要求“实现一个算法来确定一个字符串是否具有所有唯一字符。”我(可能是天真的)实现如下:

def isUniqueChars2(string):
  uchars = []
  for c in string:
    if c in uchars:
      return False
    else:
      uchars.append(c)
  return True

作者建议以下实施:

def isUniqueChars(string):
  checker = 0
  for c in string:
    val = ord(c) - ord('a')
    if (checker & (1 << val) > 0):
      return False
    else:
      checker |= (1 << val)
  return True

是什么让作者的实现比我的更好(FWIW,作者的解决方案是Java,我将其转换为Python)是我的解决方案,这是不可能用Java实现的?或者,更一般地说,解决这个问题需要什么?我采取的方法有什么问题?我假设有一些基本的CS概念(我不熟悉)很重要,有助于选择采用哪种方法解决这个问题。

8 个答案:

答案 0 :(得分:34)

以下是我写这个的方法:

def unique(s):
    return len(set(s)) == len(s)

字符串是可迭代的,因此您可以将参数直接传递给set()以从字符串中获取一组字符(根据定义,它不包含任何重复项)。如果该集合的长度与原始字符串的长度相同,那么您将拥有完全唯一的字符。

您当前的方法很好,在我看来,它比作者提出的版本更具Pythonic和可读性,但您应该将uchars更改为集合而不是列表。集合具有O(1)成员资格测试,因此如果c in uchars是集合而不是列表,uchars平均要快得多。所以你的代码可以编写如下:

def unique(s):
    uchars = set()
    for c in s:
        if c in uchars:
            return False
        uchars.add(c)
    return True

如果字符串很大且早期有重复项,这实际上会比我的版本更有效,因为它会短路(一旦找到第一个副本就退出)。

答案 1 :(得分:4)

美丽胜过丑陋。

你的方法非常好。这是python,当有很多方法可以做某事时。 (你的更漂亮:))。但是如果你真的希望它更加pythonic和/或让它变得更快,你可以使用一套,就像F.J的答案所描述的那样。

第二种解决方案看起来很难理解。

(PS,dict是内置类型。请勿覆盖它:p。string是标准库中的模块。)

答案 2 :(得分:2)

str = raw_input("Enter string: ")


def isUnique():
    test_dict = dict()
    is_unique = True
    for c in str:
        if(not test_dict.get(c, False)):
            test_dict[c] = c
        else:
            is_unique = False
            break
    if is_unique:
        return "String is unique"
    else:
        return "String is not unique"

print(isUnique())

答案 3 :(得分:1)

您的解决方案并不正确,但您的变量dict实际上并不是字典,这意味着它必须进行线性搜索以检查字符。本书的解决方案可以在恒定时间内进行检查。我会说另一个解决方案是令人讨厌的,因为它使用设置数字中的位来检查字符是否唯一

答案 4 :(得分:1)

您从Java转换为Python的解决方案就是所谓的“bit-twiddling”算法。我们的想法是可以通过多种方式处理整数:一个是数字。二,作为一个比特集合(32个开/关,或64,或什么你)。该算法通过说每个位表示特定字符​​的存在或缺失来进行比特 - 如果第n位为0,则设置它。如果它是1,那么该位对应的字符已经存在,所以我们知道没有唯一的字符。

然而,除非你需要效率,否则请避免使用比特麻烦的算法,因为它们在如何作为非比特琐事中不那么明显。

答案 5 :(得分:0)

你的实现需要O(n2),作者需要O(n)。 在你的实现中,“if c in uchars:”,当它检查这个数组中是否有c时,它必须经过整个数组,这需要时间。 所以你的并不比作者更好......

答案 6 :(得分:0)

解决方案1:

def is_unique(string):
  if len(string) > 128:
    return False

  unique_tracker = [False] * 128
  for char in string:
    if unique_tracker[ord(char)] == False:
      unique_tracker[ord(char)] = True
    else:
      return False
  return True

解决方案2:

def is_unique_bit(string):
  if len(string) > 128:
  return False

  unique_tracker = 0
  for char in string:
    ascii_val = ord(char)
    if (unique_tracker & (1 << ascii_val)) > 0:
      return False
    unique_tracker |= (1 << ascii_val)
  return True

答案 7 :(得分:0)

最初的问题是: 实现算法以确定字符串是否具有所有唯一字符。如果您不能使用其他数据结构怎么办?

关注第二句,它说我们不能使用额外的数据结构,即你需要考虑解决方案的空间复杂性。您的解决方案使用数组,因此不符合问题标准。

相关问题