word_split.erl 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. -module(word_split).
  2. -export([words/1, to_list/1]).
  3. % data WordState = {chunk, S} | {segment, L, C, R}
  4. nil() ->
  5. nil.
  6. singleton(S) ->
  7. {single, S}.
  8. conc(A, B) ->
  9. {conc, A, B}.
  10. to_list(nil) ->
  11. [];
  12. to_list({single, S}) ->
  13. [S];
  14. to_list({conc, A, B}) ->
  15. to_list(A) ++ to_list(B).
  16. maybe_word("") ->
  17. nil();
  18. maybe_word(S) ->
  19. singleton(S).
  20. process_char($ ) ->
  21. {segment, "", nil(), ""};
  22. process_char(C) ->
  23. {chunk, [C]}.
  24. combine({chunk, S1}, {chunk, S2}) ->
  25. {chunk, S1 ++ S2};
  26. combine({chunk, S}, {segment, L, C, R}) ->
  27. {segment, L ++ S, C, R};
  28. combine({segment, L, C, R}, {chunk, S}) ->
  29. {segment, L, C, R ++ S};
  30. combine({segment, L1, C1, R1}, {segment, L2, C2, R2}) ->
  31. {segment, L1, conc(C1, conc(maybe_word(R1 ++ L2), C2)), R2}.
  32. words([X|XS]) ->
  33. T = lists:foldl(fun(A, B) -> combine(B, A) end, process_char(X),
  34. lists:map(fun(C) -> process_char(C) end, XS)),
  35. case T of
  36. {chunk, C} ->
  37. maybe_word(C);
  38. {segment, L, C, R} ->
  39. conc(maybe_word(L), conc(C, maybe_word(R)))
  40. end.