Повторяющиеся символы строки на Visual Prolog

      Комментарии к записи Повторяющиеся символы строки на Visual Prolog отключены

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 6 мес., 4 нед. назад.

  • Автор
    Сообщения
  • #3465

    Напишем на языке Visual Prolog программу, выделяющую повторяющиеся символы строки. На вход функция принимает строку, в качестве результата формируется новая строка, в которую включены символы, входящие в исходную строку более одного раза. При этом, даже если символ входит в строку три и более раз — в результирующей строке он должен находиться в единственном экземпляре.

    По выполняемой работе функции эквивалентна предикату repeated_set, выполняющему выбор повторяющихся элементов списка. Разница заключается в том, что наша функция обрабатывает строку, а не список. Однако, в некоторых реализациях пролога строки представляются списками — для них нет смысла писать еще одну функцию.

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

    repeated_symbols(String, Repeated):-
      repeated_symbols(String, "", Repeated).

    Вспомогательная функция с помощью стандартного предиката frontchar отделяет от строки первый символ (Symbol), формируя в результате хвост (StringTail). С помощью функции symbol_of_string выполняется поиск символа в строке — проверка того, что Symbol входит в StringTail, т.е. входит в исходную строку более одного раза. Затем, с помощью этого же предиката проверяется отсутствие символа в уже накопленном результате (буфере). Если все эти условия выполнились — с помощью оператора отсечения ограничивается перебор с возвратами, выполняется добавление символа к буферу (также с помощью frontchar) и рекурсивная обработка остатка строки с новым буфером.

    Если же какое-либо из условий было нарушено (отсечение не было выполнено), то управление передается третьему правилу предиката. При этом исходный символ либо не повторяется в строке, либо уже был включен в результат, поэтому достаточно отделить этот символ от строк, сформировав хвост (StringTail), который нужно передать для рекурсивной обработки со старым значением буфера.

    repeated_symbols("", Buffer, Buffer):-!.
    repeated_symbols(String, Buffer, Repeated):-
      frontchar(String, Symbol, StringTail),
      symbol_of_string(StringTail, Symbol),
      NOT(symbol_of_string(Buffer, Symbol)), !,
      frontchar(BufferWithSymbol, Symbol, Buffer),
      repeated_symbols(StringTail, BufferWithSymbol, Repeated).
    repeated_symbols(String, Buffer, Repeated):-
      frontchar(String, _Symbol, StringTail),
      repeated_symbols(StringTail, Buffer, Repeated).

Для ответа в этой теме необходимо авторизоваться.