如何将输入字符串中的单词返回到Python中特定数量的字符?

时间:2014-04-17 12:39:53

标签: python algorithm knapsack-problem

在输入时,我们有很长的单词列表。我应该返回一个由输入列表中存在的单词组成的任意字符串。结果字符串的总长度应尽可能接近下限(< = 15)的15个字符(忽略空格)。据我所知,这个任务与背包问题有关。

例如:

输入:

 'This is a long string that has some words'

输出:

'This is a long that'

我的函数(但我在elif语句上有编译错误):

def return_words(string):
    MAXSYMB = 15
    if not string or string.isspace():
        return 'You did not enter any string'
    str_ign_space = string.replace(' ', '') 
    elif len(str_ign_space) <= MAXSYMB: 
        cur_str = string.split()
        return ' '.join(word for word in cur_str)
    else:
        a = [(i, len(i)) for i in cur_st]
        sorted_items = sorted(((length, word)
                       for word, length in a),
                      reverse = True)
        wt = 0
        bagged = []
        for length, word in sorted_items:
            portion = min(MAXSYMB - wt, length)
            wt     += portion
            bagged += [(word, portion)]
            if wt >= MAXSYMB:
                break
        return ' '.join(item[0] for item in bagged)

3 个答案:

答案 0 :(得分:2)

你的行

str_ign_space = string.replace(' ', '') 

分解您的if ... elif ... else条件块。您无法使用elif启动条件块,因此您将收到SyntaxError。

elif替换为常规if以启动新的条件块,您的代码将进行解析。

答案 1 :(得分:1)

elif必须指示跟随if或其他elif。你试图把这个陈述:

str_ign_space = string.replace(' ', '') 

介于 ifelif之间,这是没有意义的。相反,将该行放在if之前。这也可以让您简化if条件 - 因为您删除了所有空格,只要string.isspace()为真,您也会str_ign_space为空:

def return_words(string):
    MAXSYMB = 15
    str_ign_space = string.replace(' ', '')
    if not str_ign_space:
        # Didn't enter a string without spaces
    elif len(str_ign_space) <= MAXSYMB:
        ....

你这里也有问题:

a = [(i, len(i)) for i in cur_st]

此行直接位于else:下方,但cur_st仅在其上方的elif中定义。每当else运行时,elif 完成(按照定义),cur_st将为NameError。我想你可能意味着for i in string.split()。整个elif块非常奇怪。首先,请注意:

' '.join(word for word in cur_str)

与:

相同
' '.join(cur_str)

很明显你要在空格上拆分字符串..只是立即用空格重新连接这些部分。这有时是合理的(它将多个空格折叠为一个),但这是相当不寻常的 - 如果你故意这样做,它应该得到一个评论来解释为什么

答案 2 :(得分:0)

from collections import Counter

def find_highest_combo_lte_target(lencounts, target):
    # highest achievable values == sum of all items
    total = sum(length*num for length,num in lencounts)

    if total <= target:
        # exact solution or not reachable - return everything
        return lencounts
    else:
        # dynamic programming solution
        found = {0: []}
        for length,num in lencounts:
            new_found = {}
            for k in range(1, num+1):
                val = length * k
                if (target - val) in found:
                    return found[target - val] + [(length, k)]
                else:
                    for total,values in found.items():
                        newtotal = val + total
                        if newtotal < target and newtotal not in found:
                            new_found[newtotal] = found[total] + [(length, k)]
            found.update(new_found)
        best = max(found)
        return found[best]

def build_string(words, lencounts):
    len_num = dict(lencounts)
    result = []
    for word in words:
        wl = len(word)
        if len_num.get(wl, 0) > 0:
            result.append(word)
            len_num[wl] -= 1
    return " ".join(result)

def return_words(s, targetlen):
    words   = s.split()         
    counts  = Counter(len(word) for word in words).items()
    bestsol = find_highest_combo_lte_target(counts, targetlen)
    return build_string(words, bestsol)

def main():
    s = "This is a very long string containing some words odd and eerie"
    for i in range(30):
        print("{:>2}: {}".format(i, return_words(s, i)))

if __name__=="__main__":
    main()

产生

 0: 
 1: a
 2: is
 3: is a
 4: a odd
 5: is odd
 6: is a odd
 7: a odd and
 8: is odd and
 9: is a odd and
10: This odd and
11: This a odd and
12: This is odd and
13: This is a odd and
14: This very odd and
15: This a very odd and
16: This is very odd and
17: This is a very odd and
18: This very long odd and
19: This a very long odd and
20: This is very long odd and
21: This is a very long odd and
22: This very long some odd and
23: This a very long some odd and
24: This is very long some odd and
25: This is a very long some odd and
26: This is very long some words odd
27: This very long some words odd and
28: This a very long some words odd and
29: This is very long some words odd and