wolfram-mathematica – 时间有效的部分倒置指数建设

我需要构建一个部分 Inverted Index.这样的东西:
l = {{x,{h,a,b,c}},{y,{c,d,e}}}
iI[l]
(*
-> {{a,{x}},{b,{x,y}},{d,{y}},{e,{x}}}
*)

我觉得这是很清楚的.在输入列表中,y …}是唯一的,而{a,c,..}不是.输出应该由#[[1]]排序.

现在,我这样做:

iI[list_List] := {#,list[[Position[list,#][[All,1]]]][[All,1]]} & /@ 
                     (Union@Flatten@Last@Transpose@list)

但是看起来太慢了,我应该能够应付军团,这看起来太复杂了.

比较你的结果的测试驱动:

words = DictionaryLookup[];
abWords = DictionaryLookup["ab" ~~ ___];
l = {#,RandomChoice[abWords,RandomInteger[{1,30}]]} & /@ words[[1 ;; 3000]];
First@Timing@iI[l]
(*
-> 5.312
*)

那么,加速的任何想法?

似乎是Reap-Sow的经典任务(由于@Heike在最终版本的改进):
iI[list_] := Sort[Reap[Sow @@@ list,_,List][[2]]]

然后,

iI[l]

{{a,{x}}}

In[22]:= 
words=DictionaryLookup[];
abWords=DictionaryLookup["ab"~~___];
l={#,30}]]}&/@words[[1;;3000]];
First@Timing@iI[l]
Out[25]= 0.047

编辑

这是一个具有类似(稍差)性能的替代版本:

iIAlt[list_] :=
   Sort@Transpose[{#[[All,1,2]],#[[All,All,1]]}] &@
           GatherBy[Flatten[Thread /@ list,1],Last];

有趣的是,Reap – Sow这里给出了比基于结构操作更快的解决方案.

编辑2

只是为了说明 – 对于喜欢基于规则的解决方案的人来说,这是一个基于Dispatch和ReplaceList的组合:

iIAlt1[list_] :=
   With[{disp = Dispatch@Flatten[Thread[Rule[#2,#]] & @@@ list]},Map[{#,ReplaceList[#,disp]} &,Union @@ list[[All,2]]]]

但是,它比其他两个慢约2-3倍.

相关文章

什么是设计模式一套被反复使用、多数人知晓的、经过分类编目...
单一职责原则定义(Single Responsibility Principle,SRP)...
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强...
适配器模式将一个类的接口转换成客户期望的另一个接口,使得...
策略模式定义了一系列算法族,并封装在类中,它们之间可以互...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,...