如何用adist仅通过删除操作匹配字符串?结果异常排查
问题原因分析
adist函数的costs参数是设置编辑操作的成本权重,而非禁止对应操作。即使将替换、插入的成本设为0,算法仍会在动态规划过程中选择这些操作——因为它们能带来更低的总成本(比如遇到y中存在x没有的字符时,插入操作成本为0,会被优先选择),这就导致你看到的替换、插入计数依然存在。此外,ignore.case=TRUE只是让大小写不同的字符被视为匹配,并未限制操作类型。
仅删除操作的字符串匹配实现
要实现“仅通过删除x的字符来匹配y中元素”的需求,我们可以自定义函数,基于子序列匹配的逻辑来计算所需删除的字符数:删除数越少,匹配度越高。如果y中的元素无法通过删除x的字符得到(即y包含x没有的字符),则标记为高成本(低匹配度)。
自定义实现代码
# 计算仅删除操作的匹配成本:删除x中字符得到y所需的删除数,无法实现则返回大值 only_deletion_match <- function(target, candidate, ignore_case = TRUE) { # 统一大小写(如果需要) if (ignore_case) { target <- tolower(target) candidate <- tolower(candidate) } # 拆分字符向量 t_chars <- strsplit(target, "")[[1]] c_chars <- strsplit(candidate, "")[[1]] c_ptr <- 1 delete_count <- 0 # 双指针遍历,匹配子序列 for (char in t_chars) { if (c_ptr <= length(c_chars) && char == c_chars[c_ptr]) { c_ptr <- c_ptr + 1 } else { delete_count <- delete_count + 1 } } # 如果候选字符串未完全匹配(存在target没有的字符),返回高成本 if (c_ptr <= length(c_chars)) { return(length(t_chars) + length(c_chars)) } return(delete_count) } # 测试示例 x <- "PCOR1" y <- c("PCor", "TCor", "TMMON", "INTMAX") # 计算每个元素的匹配成本 match_costs <- sapply(y, function(elem) only_deletion_match(x, elem)) print(match_costs) #> PCor TCor TMMON INTMAX #> 1 10 10 10 # 找到匹配度最高的元素(成本最小) best_match <- y[which.min(match_costs)] print(best_match) #> [1] "PCor"
代码逻辑说明
- 首先统一大小写(如果开启
ignore_case),消除大小写差异的影响。 - 使用双指针法遍历
x的每个字符:如果当前字符与y的指针位置字符匹配,则移动y的指针;否则计数一次删除操作。 - 遍历结束后,如果
y的指针未走完所有字符,说明y包含x没有的字符,无法仅通过删除x的字符得到,返回一个较大的成本值(这里设为两个字符串长度之和,表示完全不匹配)。 - 最终成本值越小,说明匹配度越高,取成本最小的元素即为结果。
内容的提问来源于stack exchange,提问作者smoff
相关产品推荐
相关产品推荐

