我正在设计一个文字过滤器,可以过滤掉文章中的坏词(列表中的200个单词)(约2000个单词)。我有一个问题是数据结构我需要保存这个坏词列表,这样程序可以用一点时间在文章中找到坏词?
- 更多详情
如果坏词列表的大小是2000,那么文章是50000,程序将一次处理大约1000篇文章。我应该选择哪种数据结构,在搜索中少于O(n ^ 2)的解决方案?
答案 0 :(得分:1)
您可以使用HashTable,因为它的平均复杂度为插入和搜索的O(1),而您的数据只有2000个字。 http://en.wikipedia.org/wiki/Hash_table
答案 1 :(得分:1)
词典通常是从一件事(第一语言中的单词)到另一件事(第二语言中的单词)的映射。您似乎不需要此映射,只需要一组单词。
大多数语言都提供开箱即用的 set 数据结构和insert
以及成员资格测试方法。
Python中的一个小例子,比较list
和set
:
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
实现的一个示例。