【问题标题】:Find the longest common substring suffix between a string and a key in a dictionary查找字典中字符串和键之间的最长公共子字符串后缀
【发布时间】:2022-01-09 04:50:34
【问题描述】:

我正在尝试制作一个程序,输出字典中字符串和键之间的最长公共后缀字符串。

简单的例子: 该字典有大约 6000 个键:值对,所以我不会包括整个字典。有关信息,密钥长度为 2 到 7 个字符。

codeCountry = {
    'AFHAS': 'AFGHANISTAN',
    'AXUYFF': 'ÅLAND ISLANDS',
    'ALUU': 'ALBANIA',
    'DZBG': 'ALGERIA',
    'ASSQ': 'AMERICAN SAMOA',
    'ADDD': 'ANDORRA',
    'ANGO': 'ANGOLA',
    'ANGI': 'ANGUILLA',
    'AQ': 'ANTARCTICA',
    'AG': 'ANTIGUA AND BARBUDA',
    'AMENI': 'ARMENIA',
    'AURI': 'ARUBA',
    'AUR': 'ARGENTINA',
    'AURII': 'AUSTRALIA'
     ...

}

作为字符串,我将以“AMAURI”为例,这样更清楚(字符串是随机生成的,长度可变,从一个字符到 16 个字符,但它总是包含字典中的后缀(键)之一):

strToUse = "AMAURI"

预期结果:“ARUBA”,因为字符串和字典中的键之间的最长公共后缀是“AURI”所以 -> “AURI”:“ARUBA”。

我怎么能做到这一点是python?我尝试过这样的事情(我是 python 新手):

for country in codeCountry:
 if country in strToUse:
   print(codeCountry.get(country))

但这会打印出“ARGENTINA”,这是不正确的,我不明白为什么。 stackoverflow 上也有类似的问题,但我的问题是不同的,因为它查找后缀,而不仅仅是字符串中的任何字符。我希望我很清楚,我自己真的很困惑,不知道该怎么做,有人可以帮助我吗?或者至少指出我正确的方向?

【问题讨论】:

  • 出于好奇,如果输入字符串包含来自 dict 的两个相同长度的键,预期的结果是什么?示例:“AQAG”可能返回“ANTARCTICA”或“ANTIGUA AND BARBUDA”。
  • 您需要包含足够多的codeCountry 字典以提供与示例和您获得的结果相匹配的上下文。 “AMAURI”和“ARGENTINA”之间的关系(就后缀而言)尚不清楚。
  • 你真的是指后缀吗(即键正好出现在目标字符串的末尾)?如果是这样,您为什么要使用country in strToUse 而不是strToUse.endswith(country) 进行测试?您仍然需要按照Алексей Р 的建议进行排序
  • @Eric : 没有 Eric,它会返回 'ANTIGUA AND BARBUDA' 因为只考虑后缀(单词的结尾),因为没有国家/地区的键为“AQAG”
  • @martineau:我认为这个例子很清楚,“AMAURI”和“ARGENTINA”之间的关系很简单:“AMAURI”包含后缀(词尾)“AURI”,它本身就是字典中包含值“ARGENTINA”的键“AURI”。我希望这次我清楚了。

标签: python python-3.x algorithm dictionary


【解决方案1】:

您可以先按长度对键进行排序,然后检查它们

strToUse = "AMAURI"
for country in sorted(codeCountry.keys(),key=len,reverse=True):
    if country in strToUse:
        print(codeCountry.get(country))
        break
ARUBA

【讨论】:

  • 完整的解决方案适用于那些寻找相同问题的人,但我接受@АлексейР 回复,因为它很好:strToUse = "AMAURI" for country in sorted(codeCountry.keys(),key=len, reverse=True): if strToUse.endswith(country): print(codeCountry.get(country)) break
【解决方案2】:

试试下面的代码,看看它是否适合你。 stringSubsets() 返回一组可以从您的输入字符串(在您的示例中为“AMAURI”)构造的所有可能的键(国家代码)。然后在 codeCountry 字典上使用集合交集来提供与 stringSubsets() 返回的集合中的子字符串匹配的所有键。最后一行的 print 语句显示了如何提取最大匹配键的值,或者如果键不匹配则返回 None 以避免键错误。

如果由于某种原因您的输入字符串(在本例中为“AMAURI”)过长并且您需要加快代码速度,那么您可以使用更高级的东西,例如 Aho Corasick 算法。如果你走这条路,你也许可以颠倒你的方法,并实际在你的输入字符串中搜索你的 dict 中最长的键(而不是在 dict 中搜索子字符串)。这可以很好地工作,因为您的 codeCountry dict 可能不会经常更改,因此 Aho Corasick 用于运行的 trie 可以使用您的 dict 键提前构建,从而使您对输入字符串的搜索非常快。

codeCountry = {
'AFHAS': 'AFGHANISTAN',
'AXUYFF': 'ÅLAND ISLANDS',
'ALUU': 'ALBANIA',
'DZBG': 'ALGERIA',
'ASSQ': 'AMERICAN SAMOA',
'ADDD': 'ANDORRA',
'ANGO': 'ANGOLA',
'ANGI': 'ANGUILLA',
'AQ': 'ANTARCTICA',
'AG': 'ANTIGUA AND BARBUDA',
'AMENI': 'ARMENIA',
'AURI': 'ARUBA',
'AUR': 'ARGENTINA',
'AURII': 'AUSTRALIA'
}

def stringSubsets(s):
    out = set()
    for i in range(len(s)):
        for j in range(i+1, len(s)+1):
            out.add(s[i:j])

    return out

code = "AMAURI"
candidates = stringSubsets(code)
keys = candidates.intersection(codeCountry)

# results in None if no substring matches a key in dict, else give the  
# value of the longest matching key
print(None if not keys else codeCountry[max(keys)])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 2013-09-13
    • 2019-05-03
    • 2018-06-04
    相关资源
    最近更新 更多