我将如何计算数组中每个字母数字的数量? (APL)

How would I go about counting the amount of each alphanumerical in an array? (APL)

我不知道如何获取矩阵并计算每一行的字母数字值的数量。我将只接受具有我正在计算的值的矩阵。 例如,如果我得到:

ABA455  
7L9O36G                                 
DZLFPEI

我会得到类似 A:2 B:1 4:1 5:2 的第一行,并且每一行都会独立计算。 如果您也可以解释一下,我最想了解所使用的运算符。 谢谢。

以下应该适用于任何主流的 APL 实现。

让我们从一个简单的字符向量开始:

      m ← 3 7⍴'ABA455 7L9O36GDZLFPEI'
      v ← m[1;]
      v
ABA455 

我们可以通过过滤找到唯一字符,只保留与第一次出现的索引相同的元素:

      v ⍳ v
1 2 1 4 5 5 7
      ⍳ ⍴ v
1 2 3 4 5 6 7
      ( v ⍳ v ) = ⍳ ⍴ v
1 1 0 1 1 0 1
      ⎕ ← unique ← ( (v ⍳ v) = ⍳ ⍴ v ) / v
AB45 

现在我们将唯一元素与每个元素进行比较:

      unique ∘.= v
1 0 1 0 0 0 0
0 1 0 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 1 1 0
0 0 0 0 0 0 1

将这个 table 横向求和,我们得到每个唯一元素的出现次数:

      +/ unique ∘.= v
2 1 1 2 1

现在我们只需要将唯一元素与其各自的计数配对:

       unique ,[1.5] +/ unique ∘.= v
A 2
B 1
4 1
5 2
  1

让我们将其放入效用函数中:

      ∇ c ← Counts v; u
        u ← ( (v ⍳ v) = ⍳ ⍴ v ) / v
        c ← u ,[1.5] +/ u ∘.= v
      ∇ 
      Counts v
A 2
B 1
4 1
5 2
  1

现在我们需要在矩阵的每一行上应用这个函数。我们首先将矩阵拆分为向量的向量:

      ⊂[2] m
┌───────┬───────┬───────┐
│ABA455 │7L9O36G│DZLFPEI│
└───────┴───────┴───────┘

然后我们将效用函数应用于每个向量:

      Counts¨ ⊂[2] m
┌───┬───┬───┐
│A 2│7 1│D 1│
│B 1│L 1│Z 1│
│4 1│9 1│L 1│
│5 2│O 1│F 1│
│  1│3 1│P 1│
│   │6 1│E 1│
│   │G 1│I 1│
└───┴───┴───┘

Try it online!


如果您使用的是 Dyalog APL,那么关键运算符 () 正是您所需要的:

      {⍺ ⍵}⌸ 'ABA455'
┌─┬───┐
│A│1 3│
├─┼───┤
│B│2  │
├─┼───┤
│4│4  │
├─┼───┤
│5│5 6│
└─┴───┘

它采用单个操作数并为每个唯一值调用一次,将特定值作为左参数,将出现索引列表作为右参数。然而,我们对实际发生的事件不感兴趣,只对它们的计数感兴趣:

      {⍺ (≢⍵)}⌸ 'ABA455'
A 2
B 1
4 1
5 2

现在我们只需要在每一行上应用这个函数。我们可以通过拆分矩阵并使用 Each:

应用函数来做到这一点
      {⍺ (≢⍵)}⌸¨ ↓ m
┌───┬───┬───┐
│A 2│7 1│D 1│
│B 1│L 1│Z 1│
│4 1│9 1│L 1│
│5 2│O 1│F 1│
│  1│3 1│P 1│
│   │6 1│E 1│
│   │G 1│I 1│
└───┴───┴───┘

Try it online!