不规则的表达

时间:2017-06-17 19:07:44

标签: python algorithm

我有字典(单词的名字:单词的分数)。

dict = {"fe": 1, "je": 2, "jee": 3, "ain": 3, "dai": 5, "ne": 2, "ai": 2}

任何不在字典中创建单词的字符都是-1点

示例:fejeain - 1+2+3 = 6 feje**b**ain - 1+2-**1**+3 = 5

这是我的字符串

string = "feaineai"

我想为一个单词的各个部分奖励积分。他们的总和将是结果。

但是有几种方法可以计算结果:

fe-ai-ne-ai = 1+2+2+2=7
fe-ain-e-ai = 1+3-1+2=5

是否有任何算法可以帮助我? 该算法应该找到最高的结果。

3 个答案:

答案 0 :(得分:2)

考虑以下作为直接递归解决方案,tabled解决方案将使用更少的时间:

a_dict = {"fe": 1, "je": 2, "jee": 3, "ain": 3, "dai": 5, "ne": 2, "ai": 2}

string = "feaineai"

def p(w):
    if not w:
        yield 0
        return
    for word in a_dict:
        if w.startswith(word):
            for v in p(w[len(word):]):
                yield a_dict[word] + v
    for v in p(w[1:]):
        yield -1 + v

print max(p(string))

7feaineai5fejebain,为12aidaidai

答案 1 :(得分:1)

首先,不要调用变量dict。我就是这样做的:

  

修改

最后阅读用户@Dan D.的回答,这是正确的,我没有任何补充,只是在所有结果上调用max函数的子进程。

a_dict = {"fe": 1, "je": 2, "jee": 3, "ain": 3, "dai": 5, "ne": 2, "ai": 2}


def words_points(w):
  return max(sub_points(w))

def sub_points(w):
    if not w:
        yield 0
        return
    for word in a_dict:
        if w.startswith(word):
            for v in sub_points(w[len(word):]):
                yield a_dict[word] + v
    for v in sub_points(w[1:]):
        yield -1 + v



for s in ("feaineai", "fejebain", "fejeain", "aiaiai", "aiaiaije"):
  print(words_points(s))

答案 2 :(得分:1)

这是您想要使用动态编程的一个很好的例子。有很多方法可以实现这个算法,让我在下面画一个(不是最优的)。

对于每个前缀长度(0到N),您可以记住您可以为该前缀获得的最佳分数。显然,长度为0的前缀的最高分为0.您可以使用减去其长度(每个字符的-1点)初始化其他前缀。

现在,您迭代这些位置,并尝试匹配该位置的所有字典单词(让我们称之为K)。如果匹配,则更新位置的最佳分数(K +匹配单词的长度,我们称之为L)为max(分数[L],分数[k] + word_score)。最终结果将是位置分数[len(string)]。

def get_score(dct, to_score):
    dp = [-i for i in xrange(len(to_score) + 2)]
    for i in xrange(len(to_score)):
        for word in dct:
            lw = len(word)
            if lw <= len(to_score) - i:
                if word == to_score[i:i + lw]:
                    dp[i + lw] = max(dp[i+lw], dp[i] + dct[word])
        dp[i + 1] = max(dp[i + 1], dp[i] - 1)
    return dp[len(to_score)]

dct = {"fe": 1, "je": 2, "jee": 3, "ain": 3, "dai": 5, "ne": 2, "ai": 2}

for s in ("feaineai", "fejebain", "aidaidai"):
    print "%s -> %d" % (s, get_score(dct, s))