|
@@ -0,0 +1,51 @@
|
|
|
+-module(word_split).
|
|
|
+-export([words/1, to_list/1]).
|
|
|
+
|
|
|
+
|
|
|
+% data WordState = {chunk, S} | {segment, L, C, R}
|
|
|
+
|
|
|
+nil() ->
|
|
|
+ nil.
|
|
|
+
|
|
|
+singleton(S) ->
|
|
|
+ {single, S}.
|
|
|
+
|
|
|
+conc(A, B) ->
|
|
|
+ {conc, A, B}.
|
|
|
+
|
|
|
+to_list(nil) ->
|
|
|
+ [];
|
|
|
+to_list({single, S}) ->
|
|
|
+ [S];
|
|
|
+to_list({conc, A, B}) ->
|
|
|
+ to_list(A) ++ to_list(B).
|
|
|
+
|
|
|
+maybe_word("") ->
|
|
|
+ nil();
|
|
|
+maybe_word(S) ->
|
|
|
+ singleton(S).
|
|
|
+
|
|
|
+process_char($ ) ->
|
|
|
+ {segment, "", nil(), ""};
|
|
|
+process_char(C) ->
|
|
|
+ {chunk, [C]}.
|
|
|
+
|
|
|
+combine({chunk, S1}, {chunk, S2}) ->
|
|
|
+ {chunk, S1 ++ S2};
|
|
|
+combine({chunk, S}, {segment, L, C, R}) ->
|
|
|
+ {segment, L ++ S, C, R};
|
|
|
+combine({segment, L, C, R}, {chunk, S}) ->
|
|
|
+ {segment, L, C, R ++ S};
|
|
|
+combine({segment, L1, C1, R1}, {segment, L2, C2, R2}) ->
|
|
|
+ {segment, L1, conc(C1, conc(maybe_word(R1 ++ L2), C2)), R2}.
|
|
|
+
|
|
|
+words([X|XS]) ->
|
|
|
+ T = lists:foldl(fun(A, B) -> combine(B, A) end, process_char(X),
|
|
|
+ lists:map(fun(C) -> process_char(C) end, XS)),
|
|
|
+ case T of
|
|
|
+ {chunk, C} ->
|
|
|
+ maybe_word(C);
|
|
|
+ {segment, L, C, R} ->
|
|
|
+ conc(maybe_word(L), conc(C, maybe_word(R)))
|
|
|
+ end.
|
|
|
+
|