adist
使用できる@RichardScrivenの洞察を活用します(「おおよその文字列距離」を計算します。より包括的な関数を作成しました"trafos"
。2つの文字列間の「距離」を決定するために使用される「変換」を表すことに注意してください(下の例)
編集この回答は、間違った/予期しない結果をもたらす可能性があります。@wdkrnlsが指摘したように:
「apple」と「big apple bagels」に対して関数を実行したところ、「appl」が返されました。私は「リンゴ」を期待していたでしょう。
間違った結果については、以下の説明を参照してください。longest_string
リスト内のを取得する関数から始めます。
longest_string <- function(s){return(s[which.max(nchar(s))])}
次に、@RichardSriven の作品とstringi
ライブラリを使用できます。
library(stringi)
lcsbstr <- function(a,b) {
sbstr_locations<- stri_locate_all_regex(drop(attr(adist(a, b, counts=TRUE), "trafos")), "M+")[[1]]
cmn_sbstr<-stri_sub(longest_string(c(a,b)), sbstr_locations)
longest_cmn_sbstr <- longest_string(cmn_sbstr)
return(longest_cmn_sbstr)
}
または、コードを書き直して、外部ライブラリを使用しないようにすることもできます(R のネイティブadist
関数を引き続き使用します)。
lcsbstr_no_lib <- function(a,b) {
matches <- gregexpr("M+", drop(attr(adist(a, b, counts=TRUE), "trafos")))[[1]];
lengths<- attr(matches, 'match.length')
which_longest <- which.max(lengths)
index_longest <- matches[which_longest]
length_longest <- lengths[which_longest]
longest_cmn_sbstr <- substring(longest_string(c(a,b)), index_longest , index_longest + length_longest - 1)
return(longest_cmn_sbstr )
}
'hello '
上記の両方の関数は、' ではなく、最も長い共通部分文字列としてのみ識別hello r'
します (どちらの引数が 2 つのうち長いかは関係ありません)。
identical('hello',
lcsbstr_no_lib('hello', 'hello there'),
lcsbstr( 'hello', 'hello there'),
lcsbstr_no_lib('hello there', 'hello'),
lcsbstr( 'hello there', 'hello'))
最終編集
この結果の奇妙な動作に注意してください。
lcsbstr('hello world', 'hello')
#[1] 'hell'
私は期待してい'hello'
ましたが、変換が実際に (削除によって) 世界の "o" を地獄の "o" に移動するため、次のように地獄の部分のみが一致すると見なされますM
:
drop(attr(adist('hello world', 'hello', counts=TRUE), "trafos"))
#[1] "MMMMDDDMDDD"
#[1] vvvv v
#[1] "hello world"
この動作は、この Levenstein ツールを使用して観察されます。これにより、これら 2 つの変換に相当する 2 つの可能な解が得られます。
#[1] "MMMMDDDMDDD"
#[1] "MMMMMDDDDDD"
adist
あるソリューションを別のソリューションよりも優先するように構成できるかどうかわかりません。(変換の「重み」は同じです -- 「M」と「D」の数は同じです --連続 M
した数が多い変換を優先する方法がわかりません)
最後に、adist で渡すことができることを忘れないでくださいignore.case = TRUE
(FALSE
がデフォルトです)。
"trafos"
のプロパティへのキーadist
; ある文字列から別の文字列に変換する「変換」:
変換シーケンスは、戻り値の「trafos」属性として、要素M
、I
、D
およびS
一致、挿入、削除、および置換を示す文字列として返されます。