【问题标题】:How to determine whether a string is composed only of letters given by a second string如何确定字符串是否仅由第二个字符串给出的字母组成
【发布时间】:2011-01-17 14:49:27
【问题描述】:

我有两个字符串。如何确定第一个字符串是否仅由第二个字符串给出的字母组成?

例如:

A = abcd
B = abbcc

应该返回 false,因为 d 不在第二个字符串中。

A = aab
B = ab

应该返回真。

如果程序大部分时间返回false,我该如何优化这个程序?如果大部分时间都返回true,那我该如何优化呢?

【问题讨论】:

    标签: algorithm


    【解决方案1】:

    >如果程序总是返回false,如何优化这个程序?

    return false
    

    > 如果总是返回true,如何优化?

    return true
    

    编辑:说真的,这是一个很好的问题,什么算法针对失败的情况进行了优化,什么算法针对成功的情况进行了优化。我不知道 strstr 使用什么算法,它可能是一个普遍良好的算法,对于这些假设中的任何一个都不是最优的。

    也许你会在这里找到一个临时知道的人。如果没有,这似乎是一个开始阅读的好地方:Exact String Matching Algorithms

    【讨论】:

    • 也许这是一个滑稽的答案,但我不认为这真的是@skydoor 所要求的。示例和问题标题非常清楚地表明他想确定一个特定字符串的所有字符是否都出现在另一个字符串中。
    【解决方案2】:

    [如何]确定[如果]第一个字符串[由出现在]第二个字符串中的字符组成?

    这是一个快速算法:

    1. 将第一个和第二个字符串视为两组字符ST
    2. 执行 set difference S - T。调用结果U

    如果U 不为空,则返回false。否则,返回 true。

    【讨论】:

    • @skydoor,您应该澄清顺序是否重要:B 的字符是否必须按照它们在 B 中出现的顺序出现在 A 中?或者就在任何地方。
    • @profjim:是的,这是一个很好的观点。如果顺序很重要,您仍然可以进行“设置”差异,但现在您必须按特定顺序检查集合的元素。
    • 你基本上改写了这个问题而没有回答
    【解决方案3】:

    对两个字符串进行排序。然后通过 A,并有一个指针通过 B。如果 A 中的字符与 B 指针指向的字符相同,则继续查看 A。如果 A 中的字符在字母表中比 B 指针指向的字符晚到,推进 B 指针。如果 A 中的字符在字母表中比 B 指针指向的字符更早,则返回 false。如果你用完了 A,则返回 true。

    【讨论】:

      【解决方案4】:

      这是一种简单的方法。

      def isComposedOf(A, B):
          bset = set(B)
          for c in A:
              if c not in bset:
                  return False
          return True
      

      这个算法遍历每个字符串一次,所以它在 O(len(A) + len(B)) 时间内运行。

      如果答案是肯定的,即使在最好的情况下,您也不能比 len(A) 比较做得更好,因为无论如何您都必须检查每个字母。在最坏的情况下,A 中的一个字符在 B 中隐藏得很深。因此,就最坏情况的性能而言,O(len(A) + len(B)) 是最优的。

      同样:如果答案是否定的,即使在最好的情况下,你也不能比 len(B) 比较做得更好;在最坏的情况下,不在 B 中的字符在 A 中隐藏得很深。所以 O(len(A) + len(B)) 再次是最优的。

      您可以通过为bset 使用更好的数据结构来减少常数因子。

      在某些(非最坏的)情况下,您可以通过懒惰地构建它来避免扫描所有 B,每次在 A 中找到一个您以前从未见过的字符时扫描更多的 B。

      【讨论】:

      • 根据 set 的实现(是 'in' O(n)?),您可能希望在每次成功后从 bset 中删除字符。
      • 这将给出问题中第二个示例的错误答案(A="aab", B="ab")。无论如何,set 是一个哈希集,所以查询是 O(1),除非有非常多的哈希冲突。
      【解决方案5】:

      假设字符串都是小写的,那么你可以有一个位向量并根据位置position = str1[i] - 'a'设置位。设置它你会做
      bitVector |= (1<<pos)。然后对于 str2,您将检查是否在 bitVector 中为所有位设置了一个位,如果是,则返回 true,否则返回 false。

      【讨论】:

        猜你喜欢
        • 2016-02-01
        • 1970-01-01
        • 2019-11-04
        • 2021-10-04
        • 2019-12-17
        • 1970-01-01
        • 2013-04-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多