これはおそらくクレイジーなシナリオかもしれませんが、区切り文字なしで単語内のいくつかの文字を大文字で表示する方法があるかどうか疑問に思います(大文字で表示する文字を識別するため)。
例:- I/P候補者名候補者都市
O / P候補者名候補者都市
答え1
私は次のプログラムを書いたTxRこの問題を解決するためにLispを使用した。これは/usr/share/dict/words
利用可能な辞書ファイルに依存し、さらにコンピュータプログラムの識別子の一般的な略語である独自の単語を追加します。私はこれらのソースのいくつかを見つけて、いくつかを自分で追加しました。
このプログラムは、TXR Lispの組み込みトライ機能を使用して辞書からトライを構築します。ツリー構造は大規模な辞書に最適化されておらず、メモリ集約的であり、コードが少し扱いにくいので、合理化によって利点を得ることができます。
最も高いレベルでは、この関数はcamelize
質問の要件を満たすために良いと見なされる単語(通常は単一)のラクダ表記バージョンのリストを返します。
REPLを使用してナビゲートできる関数のみを残しました。
$ txr -i camel.tl
Do not operate heavy equipment or motor vehicles while using TXR.
1> (camelize "shellexecuteex")
("ShellExecuteEx")
2> (camelize "getenvptr")
("GetEnvPtr")
3> (camelize "hownowbrowncow")
("HowNowBrownCow")
4> (camelize "arcanthill")
("ArcAnthill")
5> (camelize "calcmd5digest")
("CalcMd5Digest")
6> (camelize "themother")
("TheMother" "ThemOther")
どのように機能するかは、break-word
単語のすべての可能な分割リストを返す関数です。
アルゴリズムは再帰的であり、おおよそ次のように動作します。
辞書で見つけた特定の単語のすべてのプレフィックスを見つけます。たとえば、
albumin
プレフィックスa
、alb
とを入力しますalbum
。albumin
1つ以上のプレフィックスが見つかった場合は繰り返します。各プレフィックスについて、サフィックスを単語に分割し、各可能性にプレフィックスを追加する可能な方法を見つけます。
プレフィックスが見つからない場合、その単語は辞書にないガベージ文字で始まります。この場合、その単語の連続した位置をスキャンして、辞書に出てくる単語があるかどうかを確認します。たとえば、がある場合、および
34albumin
は3
スキップ4
してa
検索されます。ゴミが分かれたら単語として扱います。ステップ2と同様に、単語の残りの部分を再帰的に結合します。
このcamelize
関数は、break-word
以下のように候補セグメントセットを取得して選択します。
各単語区分には、数値ペアで構成されるソートキーが割り当てられます。ごみの量単語の区別と長さ。ジャンクカウントは、辞書にない文字数を示します。長さは単語分割の要素数です。
1で識別されたキーに基づいてセグメントのリストをソートします。より多くのジャンク文字を含む単語セグメントは厳密に悪いと見なされます。 2つの単語セグメントに同じ数のジャンク文字が含まれている場合、より多くの部分を含む単語はより悪いと見なされます。たとえば、2つの欠陥が
themother
あります。彼らはすべてゴミ文字がゼロです。ごみの量は0です。そして両方とも長さが長い2つの要素なので、同じです。アルゴリズムはどちらも選択します。the
mother
them
other
手順2で並べ替えたら、等価キーで並べ替えをグループ化し、最適なグループを選択します。次に、このグループからCamelCaseを作成します。
ゴミはリストコメントによって単語セグメントとして識別されます(:junk "grf")
。たとえば、cat3dog
次のエラーが発生します("cat" (:junk "3") "dog")
。junk-quantity
関数のコードは、camelize
それを処理するためにいくつかの構造パターンマッチングを使用します。
長い入力には時間がかかります。たとえば、入力には数秒かかります。コードをコンパイルすると、高速化できます。このbreak-word
機能はまた、再帰検索が同じプレフィックスの組み合わせを合計しようとするため、同じサフィックスセグメンテーションを大量に計算するため、暗記の利点を享受できます。
1> (camelize "nowisthetimeforallgoodmentocometotheaidoftheircountry")
("NoWistHeTimeForAllGoodMenToComeToTheAidOfTheirCountry"
"NoWistHeTimeForAllGoodMenToComeToTheAidOftHeirCountry"
"NoWistHeTimeForAllGoodMenToComeTotHeAidOfTheirCountry"
"NoWistHeTimeForAllGoodMenToComeTotHeAidOftHeirCountry"
"NoWistHeTimeForaLlGoodMenToComeToTheAidOfTheirCountry"
"NoWistHeTimeForaLlGoodMenToComeToTheAidOftHeirCountry"
"NoWistHeTimeForaLlGoodMenToComeTotHeAidOfTheirCountry"
"NoWistHeTimeForaLlGoodMenToComeTotHeAidOftHeirCountry"
"NowIsTheTimeForAllGoodMenToComeToTheAidOfTheirCountry"
"NowIsTheTimeForAllGoodMenToComeToTheAidOftHeirCountry"
"NowIsTheTimeForAllGoodMenToComeTotHeAidOfTheirCountry"
"NowIsTheTimeForAllGoodMenToComeTotHeAidOftHeirCountry"
"NowIsTheTimeForaLlGoodMenToComeToTheAidOfTheirCountry"
"NowIsTheTimeForaLlGoodMenToComeToTheAidOftHeirCountry"
"NowIsTheTimeForaLlGoodMenToComeTotHeAidOfTheirCountry"
"NowIsTheTimeForaLlGoodMenToComeTotHeAidOftHeirCountry")
(なぜこのような結果が出るのでしょうかForaLlGood
?ll
識別子を計算する際に略語として使用され、単語としてリストされるからです。)
これでコードを入力するだけです。
(defvarl %dict% "/usr/share/dict/words")
(defun trie-dict (dict)
(let ((trie (make-trie)))
(each ((word dict))
(if (> (len word) 2)
(trie-add trie word t)))
(each ((word '#"a I ad am an as at ax be by do ex go he hi \
id if in is it lo me mi my no of oh on or \
ow ox pa pi re so to un up us we abs act \
addr alloc alt arg attr app arr auth avg \
bat bg bin bool brk btn buf char calc cb \
cert cfg ch chr circ clr cmd cmp cnt \
concat conf config conn cont conv col coll \
com cord coord cos csum ctrl ctx cur cpy \
db dbg dec def def del dest dev dev diff \
dir dis disp doc drv dsc dt en enc env eq err \
expr exch exchg fig fmt fp func ge gen gt hex \
hdr hor hw id idx iface img inc info init int \
lang lat lib le len ll lon math max mem mcu \
mid min misc mng mod msg ne net num obj ord \
op os param pic pos posix pred pref prev proc \
prof ptr pwr px qry rand rect recv rem res \
ret rev req rng rx sem sel seq stat std str \
sin sqrt src swp sync temp temp tgl tmp tmr \
tran trans ts tx txt unix usr val var vert win \
xform xmit xref xtract"))
(trie-add trie word t))
trie))
(defvarl %trie% (trie-dict (file-get-lines %dict%)))
(defun break-word (trie word)
(iflet ((lw (len word))
((plusp lw)))
(build
(let ((i 0)
(cursor (trie-lookup-begin trie)))
(whilet ((next (if (< i lw)
(trie-lookup-feed-char cursor [word i]))))
(inc i)
(set cursor next)
(if (trie-value-at next)
(let ((first-word [word 0..i])
(rest-words (break-word trie [word i..:])))
(if rest-words
(each ((rest-wordlist rest-words))
(add ^(,first-word ,*rest-wordlist)))
(add ^(,first-word))))))
(unless (get)
(for ((j 1)) ((and (< j lw) (not (get)))) ((inc j))
(let ((i j)
(cursor (trie-lookup-begin trie)))
(whilet ((next (if (and (< i lw) (not (get)))
(trie-lookup-feed-char cursor [word i]))))
(inc i)
(set cursor next)
(if (trie-value-at next)
(let ((junk-word [word 0..j])
(rest-words (break-word trie [word j..:])))
(each ((rest-wordlist rest-words))
(add ^((:junk ,junk-word) ,*rest-wordlist)))))))))
(unless (get)
(add ^((:junk ,word))))))))
(defun junk-quantity (broken-word)
(let ((char-count 0))
(each ((word broken-word))
(if-match (:junk @str) word
(inc char-count (len str))))
char-count))
(defun camelize (word)
(if (empty word)
word
(flow (break-word %trie% word)
(mapcar [juxt [juxt junk-quantity len] use])
(sort @1 : first)
(partition-by first)
first
(mapcar second)
(mapcar
(opip (mapcar (do match @(or `@{x 1}@y`
(:junk `@{x 1}@y`))
@1
`@(upcase-str x)@y`))
cat-str)))))