2016-09-22 46 views
1

我比較兩個字符串,我怎麼能得到的字符串,沒有這兩個如何使用TCL獲得無與倫比的字符串部分?

+1

您正在尋找差異化算法。這裏有幾個實現:http://wiki.tcl.tk/3108 – slebetman

+0

我的答案是基於該頁面的信息大綱; Tcllib擁有解決方案(正如它經常這樣做,只要你能找到它)。 –

回答

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] 

現在我們可以說沒有從differences是挑選部分匹配的零件addedchangeddeleted

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

如果你有一個字符串,要刪除一個固定的字符串,例如

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} 

全局用單個字符替換較大字符串中的子字符串,然後將結果拆分爲相同的字符。