插入首字母缩写词

时间:2017-01-03 21:00:27

标签: algorithm data-structures

问题:将单词翻译成首字母缩略词,缩写为单词:

  1. 前缀至少为一个字符。
  2. 后缀至少为一个字符。
  3. 中间的其余字符将替换为表示已替换的中间字符数的数字。
  4. 如果单词长度> 2,则替换的中间字符数必须> 0。
  5. 每个首字母缩略词都独特地映射到一个单词。例如,如果“abide”=> “a3e”,然后,“一边”也不能转换为“a3e”。它可以是as2e或a2de。
  6. 一些例子:

    localization => l10n 
    

    localization => loc8n 
    

    localization => l8ion
    

    解决这个问题的好方法是什么?什么样的数据结构适合?例如:HashSetTree

2 个答案:

答案 0 :(得分:0)

我会做一些观察,虽然我对解决方案没有一个非常明显的好主意。像在CS文献中一样,我会使用" string"对于一系列字母和"语言"对于一组字符串。

  • 我们不妨只考虑字符串是固定长度的字母。毕竟,没有任何缩写"本地化"可能等于"乳液"。
  • 的任何缩写
  • 当然可能没有解决方案。语言{acb,adb,aeb}无法通过您的规则正确缩写 - 甚至语言{ab}也不能缩写。这本身并不会对算法产生任何影响,但在编写代码和测试时,请记住这一点。
  • 鉴于某种语言,我们可以按照以下程序描述该语言的任何缩写:

    1. 如果语言为空:停止,我们已经完成并且我们成功了!
    2. 如果语言包含长度为2或更短的字符串:停止,我们已完成,但我们失败了。
    3. 将语言划分为子语言,这些子语言的字符串都以相同的字母开头,并且所有字母都以相同的字母结尾。例如,{ready,robby,roady,legal,loyal,regal,royal}将分为三种语言{ready,robby,roady}(所有字符串都以' r'开头并以' y'),{legal,loyal}(所有字符串都以' l'以' l'结尾)和{regal,royal}(所有字符串都以' r'开头,以' l')结尾。
    4. 对于每个子语言(例如,{ready,robby,roady}):
      1. 选择一个完全缩写的字符串;例如,我们可以选择" ready"。然后发出缩写及其映射;在这种情况下" r3y"和"准备好"。
      2. 选择语言的右 - (分别,左 - )派生减去我们发出缩写的字符串,然后从步骤1开始。将最后一个(相应的第一个)字母添加到每个发出的缩写中通过递归步骤。例如,如果我们在这里选择左派,我们会添加' r'通过递归语法{obby,oady}发出的所有缩写的开头。
    5. 你可能会有点担心步骤4-1是不是很正确;也许有时需要在递归步骤中执行 all 缩写。但很容易看出情况并非如此:如果我们必须这样做,我们当然可以改善"通过选择任何一个递归缩写并按步骤4-1的建议推广它而不引起任何冲突,缩写(在某种意义上说,删除的字母总数增加)。

      这立即建议可以浏览所有有效缩写的搜索算法。无论你想找到最好的"某些指标的缩写,或者只是想找到一个。在后一种情况下,您在步骤4中尝试选择的顺序可能会影响您发现的第一个缩写的质量,尽管我不会看到任何有原则的选择方式 - 只有启发式。 / p>

    6. 最小的DFA支持所有必要的操作(空白测试,分区,代表选择或枚举,以及左右导数),具有合理的时间效率,并且空间效率非常高。

答案 1 :(得分:0)

重述问题:从一组单词中找到一对一映射到“首字母缩略词”集(如上所述)。每个单词可以表示为前缀 | 中间 | 后缀。但是,每个单词都可以映射到 M(M + 1)/ 2 首字母缩略词,其中 M 中间的长度。示例“热”只能映射到“h1t”,热量可以映射到2(2 + 1)/ 2 = 3个首字母缩略词 - “h1at”,“he1t”,“h2t”。所以问题是任意(由于缺乏任何规定的适应度量)从每个单词的有效首字母缩略词范围中选择一个唯一值。如果我们假设一个用于替换中间字符的贪婪策略,问题解决方案会更容易(也更好)。即尽可能多地替换中间字母。请注意,由于许多单词可能映射到同一组首字母缩略词,因此可能没有足够的首字母缩写词来为每个单词指定一个首字母缩略词。在这种情况下,我们假设我们只是将单词本身指定为其首字母缩写词。

方法&数据结构:通常最好为您的问题定义伪代码解决方案,然后询问可以使用什么ADT(抽象数据类型),然后询问什么是最合适的ADT实现。在这种情况下,您需要使用难以处理的大键空间(英语单词)表示映射。一般来说,根据这个要求,你会想到一个“字典”,其中字典是支持三种操作的ADT:insert(key, valuedelete(key)search(key)(你不需要此应用程序中的delete())。字典通常实现为hash tables。首先考虑ADT的好处是底层实现可以换出,不会影响你的推理。

注意,此实例中的密钥空间有一些结构;每个单词都有三个弱键 - 它的长度,前缀,后缀 - 它们将一个单词映射到一个独特的首字母缩略词上。你可以利用它来创建一个特定于应用程序的嵌套字典,但大多数人不会在大多数应用程序中烦恼,只会使用你的语言选择字符串字典实现,因为它很简单,而且可能足够快。

以下是使用Python's dictionary type的简单解决方案。解决方案使用“贪婪的中间部分长度”方法来搜索给定单词的首字母缩略词,如果没有找到首字母缩写词,则会逐字逐句地转换为单词:

class Acronym():
  ''' Convenience class to rep the acronyms of a word. ''' 
  word = None

  def __init__(self, word):
    self.word = word

  def __iter__(self):
    ''' Loop over the M(M+1)/2 possible acronyms largest middle first. '''
    for m in reversed(range(1,len(self.word) - 1)):
      for i in range(1,len(self.word) - m):
        yield (self.word[0:i], str(len(self.word[i:i+m])), self.word[i+m:])

my_acronyms = {} # my_acronyms is a Python dictionary
my_words = ["hot", "hit", "hard", "heat", "have", "hoon", "halve"];
for word in my_words:
  acronym = Acronym(word)
  found_acronym = False
  for split in acronym:
    if not my_acronyms.get(''.join(split)): # search(key)
      my_acronyms[''.join(split)] = word
      found_acronym = True
      break
  if not found_acronym:
    my_acronyms[word] = word # insert(key, value)
print(my_acronyms)