単語の辞書があり、迅速な実装が必要な場合、辞書検索が O(1) であると仮定すると、これは O(n^2) 時間で動的プログラミングを使用して効率的に解決できます。以下はいくつかの C# コードです。部分文字列の抽出と辞書検索が改善される可能性があります。
public static String[] StringToWords(String str, HashSet<string> words)
{
//Index of char - length of last valid word
int[] bps = new int[str.Length + 1];
for (int i = 0; i < bps.Length; i++)
bps[i] = -1;
for (int i = 0; i < str.Length; i++)
{
for (int j = i + 1; j <= str.Length ; j++)
{
if (bps[j] == -1)
{
//Destination cell doesn't have valid backpointer yet
//Try with the current substring
String s = str.Substring(i, j - i);
if (words.Contains(s))
bps[j] = i;
}
}
}
//Backtrack to recovery sequence and then reverse
List<String> seg = new List<string>();
for (int bp = str.Length; bps[bp] != -1 ;bp = bps[bp])
seg.Add(str.Substring(bps[bp], bp - bps[bp]));
seg.Reverse();
return seg.ToArray();
}
/usr/share/dict/words の単語リストを使用して hastset を作成し、次のコマンドでテストします
foreach (var s in StringSplitter.StringToWords("thisisastringwithwords", dict))
Console.WriteLine(s);
「単語を含む文字列」という出力が得られます。他の人が指摘しているように、このアルゴリズムは有効なセグメンテーション (存在する場合) を返しますが、これは期待するセグメンテーションではない可能性があります。短い単語が存在すると、セグメンテーションの品質が低下します。2 つの有効なサブセグメンテーションが要素に入った場合、ヒューリスティックを追加して長い単語を優先できる場合があります。
複数のセグメンテーションを生成し、確率的ランキングを適用できる有限状態マシンと言語モデルを使用する、より洗練された方法があります。