说我有3个符号的列表:
l:`s1`s2`s3
生成以下n *(n + 1)/ 2个置换列表的q方法是什么?
(`s1;`s1),(`s1;`s2),(`s1;`s3),(`s2;`s2),(`s2;`s3),(`s3;`s3)
这可以看作是在相关矩阵的上下文中,在这里我需要相关矩阵的所有上三角部分,包括对角线。
当然,我的初始列表的大小将超过3,因此,我希望使用通用函数来执行此操作。
我知道如何生成对角线元素:
q) {(x,y)}'[l;l]
(`s1`s1;`s2`s2;`s3`s3)
但是我不知道如何生成非对角元素。
您可能会发现有用的另一种解决方案:
q)l
`s1`s2`s3
q){raze x,/:'-1_{1_x}\[x]}l
s1 s1
s1 s2
s1 s3
s2 s2
s2 s3
s3 s3
这使用scan accumulator创建符号列表的列表,每个符号列表都删除第一个元素:
q)-1_{1_x}\[l]
`s1`s2`s3
`s2`s3
,`s3
需要额外的-1_
,因为扫描也会在最后返回一个空列表。然后使用each-right和each将该列表的每个元素连接到此结果上:
{x,/:'-1_{1_x}\[x]}l
(`s1`s1;`s1`s2;`s1`s3)
(`s2`s2;`s2`s3)
,`s3`s3
最后使用raze获取不同的排列。
编辑:也可以使用
q){raze x,/:'til[count x]_\:x}l
s1 s1
s1 s2
s1 s3
s2 s2
s2 s3
s3 s3
它根本不需要扫描,并且与扫描解决方案的性能非常相似!
我会尝试下面的代码
{distinct asc each x cross x}`s1`s2`s3
It
cross
生成所有(s_i,s_j)对asc each
按索引对每一对进行排序,因此`s3`s1
成为`s1`s3
distinct
删除重复项不是很简短的最有效的方法。
[如果我理解了这个问题(如果我错过了一些东西,表示歉意)。下面应该给您您正在寻找的]
q)test:`s1`s2`s3`s4`s5
q)(til cnt) _' raze (-1+cnt:count test)cut test,'/:test
(`s1`s1;`s2`s1;`s3`s1;`s4`s1;`s5`s1)
(`s2`s2;`s3`s2;`s4`s2;`s5`s2)
(`s3`s3;`s4`s3;`s5`s3)
(`s4`s4;`s5`s4)
,`s5`s5