1个稳定版本
1.0.2 | 2022年12月29日 |
---|---|
1.0.1 |
|
1.0.0 |
|
#1283 in 算法
705 每月下载量
用于 3 个crate(通过 kn)
36KB
204 行
幂次系数
幂次系数 是一种字符串上的统计量,用于判断一个字符串是否是另一个字符串的“缩写”。函数不是对称的,因此它不是一个度量。
- 设
T
(文本)为非空字符串。 - 设
P
(模式)为T
的非空子序列。 - 设
p
为P
的一个划分,且p_i
为其元素,其中- 每个
p_i
都等于T
的某个子字符串t_i
。 - 子字符串
t_i
不重叠。 t_i
的顺序与p_i
相同。
- 每个
幂次系数是长度最短划分 p
的元素数量减一。或者,它是子字符串 t_i
之间的间隙数量。
使用术语
- 子字符串是由连续元素组成的子序列。子序列不一定是子字符串。例如,
xz
是xyz
的子序列,但它不是其子字符串。 - 序列的划分是多个两两不相交的子序列序列,当连接时等于整个原始序列。
直观解释
将模式中的所有字符取出来,同时保持原始顺序,与文本中的相同字符对齐,使字符组尽可能少。系数是这些组之间的间隙数量。
示例
P |
T |
p |
幂次系数 |
---|---|---|---|
powcoeff |
powierża coefficient |
pow ,coeff |
1 |
abc |
a_b_c |
a ,b ,c |
2 |
abc |
abc |
abc |
0 |
abc |
xyz |
— | 未定义 |
更多示例请见 测试。
用例
权重系数在kn
和nushell
中用于确定哪些目录名与缩写的匹配度更高。许多其他字符串系数和指标都被认为不合适,包括莱文斯坦距离(Levenshtein distance)。莱文斯坦距离倾向于短字符串。例如,从gra
到programming
的莱文斯坦距离大于到gorgia
的距离,尽管它并不“相似”于缩写。Powierża coefficient对于这些字符串对是0和2,因此会选择(正确地)programming
。
Powierża算法
该算法受到了Wagner–Fischer算法的启发。它也与最长公共子序列问题的解决方案非常相似。所有这些算法都是基于矩阵的。在Wagner-Fischer算法(WF)中存在三种类型的移动(水平、对角线和垂直),而我的算法中只有两种——水平和对角线。主要思想是,不管多长,间隙的成本总是1(在WF中,间隙的成本是其长度)。
这意味着算法必须区分由水平移动和由对角线移动填充的单元格。第一种类型的单元格包含Gap(score)
;第二种类型是Continuation(score)
。如果原始单元格包含Gap(score)
,则水平移动会产生Gap(score)
;如果原始单元格包含Continuation(score)
,则会产生Gap(score + 1)
。算法倾向于产生较低分数的移动,如果对角线移动和水平移动产生相同的分数,则偏好对角线移动。
-
创建一个行数为
m
、列数为n
的矩阵m
,其中m
是S
的长度,n
是P
的长度。n
必须小于或等于m
。每个单元格可以是空的(这是初始状态)或包含Gap(score)
或Continuation(score)
。 -
从左到右、从上到下填充矩阵。第一行是特殊的——如果
S
的第xth
个元素和P
的第yth
个元素相等,则第xth
和第yth
个单元格设置为Continuation(0)
。否则,设置为Gap(score + cost)
,其中score
是左侧邻居的分数。如果其左侧邻居是空的,则该单元格也保持为空。 -
其他单元格的填充规则如下
设
x
为a
的左上邻居,y
为其左邻居x _ y a
斜向移动的成本为0,但只有在
S
的xth
元素和P
的yth
元素相等,并且x
不为空时才能进行这种移动。移动后,a
被设置为Continuation(score)
,其中score
是x
的分数。如果
y
包含Gap
,则水平移动的成本为0;如果包含Continuation
,则成本为1。这种移动只有在y
不为空时才能进行。移动后,a
被设置为Gap(score + cost)
,其中score
是y
的分数。- 如果没有可用移动,则保持
a
为空。 - 如果只有一个可用移动,则执行它。
- 如果有两个可用移动且它们的分数相等,则执行水平移动。
- 如果有两个可用移动且它们的分数不相等,则执行分数最低的移动。
- 如果没有可用移动,则保持
-
幂次系数是最后一行的最小值。在某些情况下,最后一行没有值,因此系数未定义。
示例
带有G的单元格是通过水平移动填充的,而带有C的单元格是通过斜向移动填充的。字母旁边的数字是单元格的分数。红色单元格由于优化而被跳过。黄色单元格被留空。系数是2。
基准测试
在作者计算机上运行的基准测试中,该算法与strsim的levenshtein
进行了比较
- Levenshtein距离:
[1.2908 µs 1.2946 µs 1.2987 µs]
- 幂次系数:
[1.7718 µs 1.7748 µs 1.7778 µs]