保存字典的好数据结构是什么?

时间:2015-01-17 12:15:14

标签: dictionary data-structures

我正在设计一个文字过滤器,可以过滤掉文章中的坏词(列表中的200个单词)(约2000个单词)。我有一个问题是数据结构我需要保存这个坏词列表,这样程序可以用一点时间在文章中找到坏词

- 更多详情

如果坏词列表的大小是2000,那么文章是50000,程序将一次处理大约1000篇文章。我应该选择哪种数据结构,在搜索中少于O(n ^ 2)的解决方案?

4 个答案:

答案 0 :(得分:1)

您可以使用HashTable,因为它的平均复杂度为插入和搜索的O(1),而您的数据只有2000个字。 http://en.wikipedia.org/wiki/Hash_table

答案 1 :(得分:1)

词典通常是从一件事(第一语言中的单词)到另一件事(第二语言中的单词)的映射。您似乎不需要此映射,只需要一组单词。

大多数语言都提供开箱即用的 set 数据结构和insert以及成员资格测试方法。

Python中的一个小例子,比较listset

import random
import string
import time

def create_word(min_len, max_len):
    return "".join([random.choice(string.ascii_lowercase) for _ in
                    range(random.randint(min_len, max_len+1))])

def create_article(length):
    return [create_word(3, 10) for _ in range(length)]

wordlist = create_article(50000)
article = " ".join(wordlist)
good_words = []
bad_words_list = [random.choice(wordlist) for _ in range(2000)]

print("using list")
print(time.time())
for word in article.split(" "):
    if word in bad_words_list:
        continue
    good_words.append(word)

print(time.time())

good_words = []
bad_words_set = set(bad_words_list)

print("using set")
print(time.time())
for word in article.split(" "):
    if word in bad_words_set:
        continue
    good_words.append(word)

print(time.time())

这会创建一篇"文章" 50000随机创建"单词"长度在3到10个字母之间,然后选择2000个单词作为"坏单词"。

首先,它们被放入list和"文章"如果一个单词是in这个坏单词列表,则逐字扫描。在Python中,in运算符测试成员资格。对于无序列表,没有比扫描整个列表更好的方法了。

第二种方法使用使用坏词列表初始化的set数据类型。如果包含元素,set没有排序,但方式更快查找(再次使用in关键字)。这似乎是你需要知道的全部。

在我的机器上,时间是:

using list
1421499228.707602
1421499232.764034
using set
1421499232.7644095
1421499232.785762

因此,一个列表需要大约4秒钟,而一组列表需要2秒钟。

答案 2 :(得分:0)

我认为最好的结构,你可以使用set。 - http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29

我花费log_2(n)时间将元素添加到结构(一次性操作),每个查询都回答相同的问题。因此,如果您在数据结构中有200个元素,那么您的程序将只需要执行大约8个操作来检查,该单词是否存在于set中。

答案 3 :(得分:0)

此问题需要Bag数据结构。在Bag数据结构中,元素没有顺序,但设计用于快速查找Bag中的元素。时间复杂度为O(1)。因此,对于文章中的N个单词,整体复杂性结果为O(N)。在这种情况下,哪个是最好的。 Java Set是Java中Bag实现的一个示例。