Ответ в теме: Преобразование строки в список слов

      Комментарии к записи Ответ в теме: Преобразование строки в список слов отключены
#1920

Вам надо рассматривать строку как набор слов — в этом случае алгоритм очень прост:

  1. если в строке нет слов — вернуть пустой список в качестве результата;
  2. отделить первое слово от строки. Остальную часть строки — обработать рекурсивно, к результату добавить первое слово.

Отсутствие в строке слов не означает, что строка пуста — с ней могут содержаться пробелы, однако, от такой строки не получиться отделить слово. Таким образом, функция пытается удалить отделить слово, а если что-то пошло не так — вернет пустой список:

string_to_words(String, [Word|ListTail]):-
get_word(String, Word, StringTail), !, 
string_to_words(StringTail, ListTail).
string_to_words(_String, []).

Функция получения первого слова должна учитывать, что в начале строки могут содержаться пробелы и удалять их, кроме того, именно в нее целесообразно поместить проверку отсутствия слов в строке:

get_word(String, Word, StringTail):-
rem_init_spaces(String, StringWithoutInitSpaces),
StringWithoutInitSpaces \= "",
get_ExistWord(StringWithoutInitSpaces, Word, StringTail).

Функция удаляет из строки начальные пробелы, проверяет что полученная в результате строка не пуста (в ней есть слова) и вызывает функцию get_ExistWord, которая вернет первое слово.

Функция удаления начальных пробелов использует стандартный предикат is_space для проверки того, является ли символ пробельным (в т.ч. табуляцией, переводом строки и т.п.), при необходимости его можно заменить на собственную функцию:

rem_init_spaces([Char|TailStr], StringWithoutInitSpaces):-
is_space(Char), !, 
rem_init_spaces(TailStr, StringWithoutInitSpaces).
rem_init_spaces(String, String):-!.

Если первый символ строки — пробел, функция вернет результат рекурсивного вызова для остальной части строки, а в противном случае — исходную строку.

Функция выделения первого слова должна завершать вычисления если на вход подана пустая строка или первый символ является пробельным. В остальных случаях она отделяет первый символ строки (он будет первым символом слова) и рекурсивно вычисляет остальные символы слова:

get_ExistWord("", "", ""):- !.
get_ExistWord([Char|StringTail], "", StringTail):-
is_space(Char), !.
get_ExistWord([Char|StringTail], [Char|WordTail], StringWithoutWord):-
get_ExistWord(StringTail, WordTail, StringWithoutWord).