2011-09-07 70 views
8

我想开发一个python算法来检查一个字符串是否可以作为另一个单词的缩写。例如,检查一个字符串是否可以缩写为一个名字

  • fck是匹配fc kopenhavn,因为它匹配单词的第一个字符。 fhk不匹配。
  • fco不应该匹配fc kopenhavn因为没有人会将FC Kopenhavn简写为FCO。
  • irlin real life的匹配项。
  • ifk是匹配ifk goteborg
  • aik是匹配allmanna idrottskluben
  • aidallmanna idrottsklubben的匹配。这不是一个真正的团队名称缩写,但我想这很难排除它,除非您应用领域特定的知识如何形成瑞典缩写。
  • manumanchester united的匹配结果。

这是很难描述算法的精确规则,但我希望我的例子显示我后。

更新我犯了一个错误,显示匹配字母大写的字符串。在真实情况下,所有字母都是小写字母,因此不像检查哪些字母是大写字母那样容易。

+0

所以你想看看字符串是否只匹配那些字符串中的大写字母?如果是这样,请尝试为它写一些东西:只需要把你的全部东西的大写字母和它们放在字典中(作为具有完整版本的键作为值),然后很容易查找它。事实上,你并没有真正问过一个问题...... –

+0

我能想到的最好的事情是提取所有大写字母,将短字符串转换为大写,然后进行相等性测试。 –

+0

Semi-OT:虽然ManU被广泛用作非英语国家的缩写,但ManU可以被视为对ManUnited粉丝的侮辱。 –

回答

8

这通过了所有的测试,包括一些额外的创建。它使用递归。下面是我使用的规则:

  • 的缩写的第一个字母必须的 第一个字母文字
  • 的缩写(的缩写减去首字母)的其余部分匹配必须是一个缩写为:

    • 剩余的词,或
    • 剩余的文本从 在第一字中的任何位置开始。

tests=(
    ('fck','fc kopenhavn',True), 
    ('fco','fc kopenhavn',False), 
    ('irl','in real life',True), 
    ('irnl','in real life',False),  
    ('ifk','ifk gotebork',True), 
    ('ifko','ifk gotebork',False),  
    ('aik','allmanna idrottskluben',True), 
    ('aid','allmanna idrottskluben',True), 
    ('manu','manchester united',True), 
    ('fz','faz zoo',True), 
    ('fzz','faz zoo',True), 
    ('fzzz','faz zoo',False),  
    ) 

def is_abbrev(abbrev, text): 
    abbrev=abbrev.lower() 
    text=text.lower() 
    words=text.split() 
    if not abbrev: 
     return True 
    if abbrev and not text: 
     return False 
    if abbrev[0]!=text[0]: 
     return False 
    else: 
     return (is_abbrev(abbrev[1:],' '.join(words[1:])) or 
       any(is_abbrev(abbrev[1:],text[i+1:]) 
        for i in range(len(words[0])))) 

for abbrev,text,answer in tests: 
    result=is_abbrev(abbrev,text) 
    print(abbrev,text,result,answer) 
    assert result==answer 
+0

织补,打我30秒:) +1 –

+0

对不起,所有的字符串应该是全部小写。原文中全部为小写。 –

0

你的算法似乎很简单 - 缩写为全部大写字母的连接。 so:

upper_case_letters = "QWERTYUIOPASDFGHJKLZXCVBNM" 
abbrevation = "" 
for letter in word_i_want_to_check: 
    if letter in letters: 
     abbrevation += letter 
for abb in _list_of_abbrevations: 
    if abb=abbrevation: 
     great_success() 
+3

你可以使用'string.ascii_uppercase' –

+0

这会更好:/ – Dominik

0

这可能是够好的了。

def is_abbrevation(abbrevation, word): 
    lowword = word.lower() 
    lowabbr = abbrevation.lower() 

    for c in lowabbr: 
     if c not in lowword: 
      return False 

    return True 

print is_abbrevation('fck', 'FC Kopenhavn') 
+0

这是不正确的,例如尝试'print is_abbrevation('fkc','FC Kopenhavn')' –

4

这里完成你仿佛想要做

import re  
def is_abbrev(abbrev, text): 
    pattern = ".*".join(abbrev.lower()) 
    return re.match("^" + pattern, text.lower()) is not None 

插入符号可以确保的缩写的第一个字符单词的第一个字符相匹配的方式,它应该是真实的大多数缩写。

编辑: 您的新更新稍微改变了规则。通过使用"(|.*\s)"而不是".*",缩写中​​的字符只有在彼此相邻时才会匹配,或者下一个字符出现在新单词的开头。

这将正确匹配fckFC Kopenhavn,但fco不会。 但是,匹配aikallmanna idrottskluben而不是工作,因为这需要知识的瑞典语言,并不是微不足道的事情。

这里是新的代码用稍作修改

import re  
def is_abbrev(abbrev, text): 
    pattern = "(|.*\s)".join(abbrev.lower()) 
    return re.match("^" + pattern, text.lower()) is not None 
4

@Ocaso Protal在评论how should you decide that aik is valid, but aid is not valid?说,他是对的。

我想到的算法是与word threshold(用空格分隔的词的数量)一起工作。

words = string.strip().split() 
if len(words) > 2: 
    #take first letter of every word 
elif len(words) == 2: 
    #take two letters from first word and one letter from other 
else: 
    #we have single word, take first three letter or as you like 

你必须定义你的逻辑,你不能盲目地找到缩写。

相关问题