如何使用TCL获得无与伦比的字符串部分?

时间:2016-09-22 09:42:43

标签: tcl

我正在比较两个字符串,我如何得到这两个

之间不匹配的字符串部分

2 个答案:

答案 0 :(得分:2)

这是一个有趣的问题,需要最长的公共子序列算法。 Tcl有一个已经在Tcllib中的那个,但它是用于列表的。幸运的是,我们可以将字符串转换为split的字符列表:

package require struct::list

set a "the quick brown fox"
set b "the slow green fox"

set listA [split $a ""]; set lenA [llength $listA]
set listB [split $b ""]; set lenB [llength $listB]

set correspondences [struct::list longestCommonSubsequence $listA $listB]
set differences [struct::list lcsInvertMerge $correspondences $lenA $lenB]

现在,我们可以通过选择differencesaddedchanged {/ 1}}中的deleted部分来获取不匹配的部分:

set common {}
set unmatchedA {}
set unmatchedB {}
foreach diff $differences {
    lassign $diff type rangeA rangeB
    switch $type {
        unchanged {
            lappend common [join [lrange $listA {*}$rangeA] ""]
        }
        added {
            lappend unmatchedB [join [lrange $listB {*}$rangeB] ""]
        }
        changed {
            lappend unmatchedA [join [lrange $listA {*}$rangeA] ""]
            lappend unmatchedB [join [lrange $listB {*}$rangeB] ""]
        }
        deleted {
            lappend unmatchedA [join [lrange $listA {*}$rangeA] ""]
        }
    }
}

puts common->$common
# common->{the } ow {n fox}
puts A->$unmatchedA
# A->{quick br}
puts B->$unmatchedB
# B->sl { gree}

在这种情况下,我们看到以下对应关系(.是我插入的间隔符以帮助排列):

the quick br..ow.....n fox
the ........slow green fox

这是否正是你想要的,我不知道(计算差异中有更多细节;它们只是有点难以阅读)。如果更符合您的口味,您可以轻松切换到逐字对应。它只是删除splitjoin ...

答案 1 :(得分:1)

如果您有一个字符串,并且想要删除固定的子字符串,例如

set str "this is a larger? string"
set substr "a larger?"

然后你可以这样做:

set parts [split [string map [list $s2 \uffff] $s1] \uffff]
# returns the list: {this is } { string}

全局使用单个字符替换较大字符串中的子字符串,然后将结果拆分为相同的字符。