我有一个数组arr
条目,我有一个entryA
。我的目标是找到与arr
最相关的entryA
条目。
我决定使用标记出现次数和组成员资格来排序arr
。我希望尽可能减少时间和空间:
# For some entry entryX in array arr:
entryX.tag_list #returns the array of tags for entryX
entryX.groups #returns the array of groups for entryX
entryA.user #returns the user who created entryA
# Similarly, for entryA
entryA.tag_list #returns the array of tags for entryA
entryA.groups #returns the array of groups for entryA
entryA.user #returns the user who created entryA
我想对数组arr
进行排序,使得arr
中与entryA
共享最多相同组的条目,entryA.tag_list
中相同标签的数量最多并且由同一个用户创建将具有优先权,并将定位在arr[0]
。所以我想为每个共享组分别设置1,每个标记共享1个,如果由同一个用户创建,则为2个。
实现这一目标的最佳算法是什么?
答案 0 :(得分:1)
{original_entry_index, closeness_to_A_score}
。closeness_to_A_score
closeness_to_A_score
降序创建的数组。O(N)空间复杂度和O(N * log(N))时间复杂度。
在为“共享标签”和“共享组”的得分做出贡献时,可能会出现一些惊喜 - 如果您可以将它们存储在哈希集(最佳)或排序集(足够好)而不是列表中(呻吟) !),计算交叉点中的元素将尽可能快地计算。
答案 1 :(得分:1)
发布Adrian的回答。您已经为数组中的项描述了一种分类器。现在你需要用你的规则来实现它。
为了应用它,您可以使用Enumerable#sort_by
,除了分类之外,它正是Adrian所说的。此方法将根据分类等级对元素进行排序。考虑到,您需要在列表顶部使用最相似的元素,您需要将.inverse
添加到结果数组中。
解决方案的可能模板之一可能如下所示
def classifier_generator(sample)
lambda do |entry|
# calculation of similarity based on sample and entry values
end
end
grader = classifier_generator(entryA)
arr.sort_by &grader .inverse
答案 2 :(得分:1)
TAG_LIST_UNIT_VALUE = 1
GROUPS_UNIT_VALUE = 1
SAME_USER_VALUE = 2
def score(entryA, entryX)
TAG_LIST_UNIT_VALUE * (entryA.tag_list & entryX.tag_list).size +
GROUPS_UNIT_VALUE * (entryA.groups & entryX.groups).size +
(entryA.user == entryX.user) ? SAME_USER_VALUE : 0
end
arr.sort_by { |entryX| -score(entryA, entryX) }
entryA.tag_list & entryX.tag_list
是entryA
和entryX
共有的群组数组。类似于groups
。 score
返回的值被否定以使排序减少。