我最近不得不编写以下算法:
给出一组标签和一组标签 博客文章,博客文章可能 包含零对多标签,返回 所有帖子共有的标签。
这种比较是在内存中完成的 - 访问集合不导致网络中的旅行(即,到数据库等)。
此外,Tags
集合没有对包含它的BlogPosts
的引用。 BlogPosts
包含Tags
的集合。
以下是我的实施。它表现得很好,但我很好奇是否有更好的方法来实现它。
我的实现是在Actionscript中,但我对algorithim的观点更加好奇,所以任何语言的例子都很好。 (但如果我不懂语言,我可能会要求你澄清一些方面)
任何改进的例子都会受到极大的欢迎。
private function getCommonTags(blogPosts:Vector.<BlogPost>):Vector.<Tag>
{
var commonTags:Vector.<Tag> = new Vector.<Tag>();
if (!blogPosts || blogPosts.length == 0)
return commonTags;
var blogPost:BlogPost = blogPosts[0];
if (!blogPost.tags || blogPost.tags.length == 0)
return commonTags;
commonTags = Vector.<Tag>(blogPosts[0].tags);
for each (var blogPost:BlogPost in blogPosts)
{
if (!blogPost.tags || blogPost.tags.length == 0 || commonTags.length == 0)
// Updated to fix bug mentioned below
// Optomized exit - there are no common tags
return new Vector.<Tag>();
for each (var tag:Tag in commonTags)
{
if (!blogPost.containsTagId(tag.id))
{
commonTags.splice(commonTags.indexOf(tag),1);
}
}
}
return commonTags;
}
答案 0 :(得分:1)
嗯,你只需要一个有效的算法来计算两组的交集,因为你可以反复调用两组以上的算法。
快速算法是将第一组的项添加到哈希表中,然后遍历第二组,检查哈希表以查看它是否存在;如果是,则将其添加到交叉点中要返回的项目列表中。
答案 1 :(得分:0)
我可以用英文句子说明这个程序:“返回帖子中统一出现的所有标签。”
将名称all_tags
提供给代码列表,将post_tags
提供给与帖子关联的代码列表,我可以在J programming language中对此句话说同样的话
all_tags #~ (#=+/) all_tags e.&>"_ 0 post_tags
详细看一下:
#~
表示“复制在哪里”
(# = +/)
表示“理货等于总和”
e.
表示“存在于”
&>"_ 0
修改e.
,以便将all_tags
的整体与post_tags
如果我们想让这个程序带有两个参数,而不是一个特定于这些命名列表的程序,那么相应的程序可能是:
common_to=: [ #~ [:(#=+/) [ e.&>"_ 0 ]
使用相同的数据名运行该程序将如下所示:
all_tags common_to post_tags
似乎值得注意的是,我们实际上并不需要全面的标签列表,因为可以派生出来。 (计算结果为~. ; post_tags
。)这意味着我们可以编写程序只采用一个参数。但由于问题假设我们已经计算了all_tags
列表,因此无需再次计算它。