使用斐波那契数列打印单词

3 投票
2 回答
806 浏览
提问于 2025-04-16 15:46

我正在写一个程序,这个程序会打印出一个单词的出现频率,只要这个频率是斐波那契数列中的数字(比如1, 2, 3, 5, 8等等)。我已经搞定了如何打印出出现一次的所有单词,但我现在遇到麻烦了,不知道怎么去循环打印出出现频率更高的单词。

import string
import itertools

def fib():
    a,b = 0, 1
    while 1:
        yield b
        a, b = b, a + b

while True:
    filename = raw_input('Enter a file name: ')
    if filename == 'exit':
        break
    try:
        file = open(filename, 'r') 
        text = file.read() 
        file.close() 
    except:
        print('file does not exist')
    else:

        for word in string.punctuation:
            text=text.replace(word, "")
        word_list = text.lower().split(None)
        word_freq = {}

        for word in word_list:
            if len(word) > 1:
                word_freq[word] = word_freq.get(word, 0) + 1

        frequencies = sorted(word_freq.items(), key=lambda item: item[1])
        a = fib()
        order = sorted(word_freq.values())
        n = 1
        a = next(a)
        for words in frequencies:
            try:
                if a == words.index(n):
                    print(words)
            except:
                print('nope')  # HELP: how would I iterate here??


print('Bye')

2 个回答

1

你在调用 next 的时候,把生成器对象给覆盖掉了。

调用 fib() 会返回一个生成器。要获取下一个值,你需要用 next(a),这样就能得到值。然后你把这个值赋给 a,这样就覆盖掉了你的生成器,所以你就不能再用了。正确的做法是像这样 value = a.next(),每次需要获取斐波那契数列的下一个值时执行这个。

顺便说一下,可能更合理的做法是遍历斐波那契数,而不是遍历频率。否则,每次你都得重置你的斐波那契生成器。

你可以在列表中找到最大频率,然后一旦斐波那契数列超过这个值,就停止迭代。

1

试着把你的 while 循环的结尾改成下面这样:

    f = next(a)
    for words in frequencies:
        # we need a new value from fib, since we have passed the current one
        while words[1] > f:
            f = next(a)
        # if the frequency of this word matches the fib value, print it
        if words[1] == f:
            print(words)

撰写回答