Задача на Visual Prolog. Вычеркивание букв

      Комментарии к записи Задача на Visual Prolog. Вычеркивание букв отключены

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

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

    Nika
    Участник

    Имеется задача: составьте программу вычеркивания из слова всех букв, стоящих на четных местах после буквы “о”.

    Есть решение:

    predicates
    nondeterm del_after_o(string,integer,char,string)
    nondeterm del_o(string,string)
    
    clauses
    del_after_o(“”,_,_,””).
    del_after_o(S,N,P,R):- 
      N1=N+1, P=’o’, 
      (N mod 2)=0, 
      frontchar(S,A,B),
      del_after_o(B,N1,A,R).
    del_after_o(S,N,P,R):- 
      N1=N+1, P<>’o’, 
      frontchar(S,A,B), 
      del_after_o(B,N1,A,RR), 
      frontchar(R,A,RR).
    del_after_o(S,N,P,R):- 
      N1=N+1, P=’o’, 
      (N mod 2)<>0, 
      frontchar(S,A,B), 
      del_after_o(B,N1,A,RR), 
      frontchar(R,A,RR).
    
    del_o(S,R):- 
      frontchar(S,A,_), 
      delo(S,1,A,R).
    
    goal 
      del_o (“odammm”, X).

    Однако, работает данная программа только если слово начинается на букву “о”, и вычеркивает только одну букву.

    Можете ли вы помочь с объяснение данной задачи, пожалуйста.

  • #2847

    Я не понимаю как должна работать ваша программа, но я бы решил задачу примерно так:

    remove_even_after_symbol([], _Symbol, []):-!.
    remove_even_after_symbol([SingleElement], _Symbol, [SingleElement]):-!.
    remove_even_after_symbol([Symbol, _UnwantedSymbol|Tail], Symbol, [Symbol|TailResult]):-
      !, remove_even_after_symbol(Tail, Symbol, TailResult).
    remove_even_after_symbol([A, B|Tail], Symbol, [A, B|TailResult]):-
      remove_even_after_symbol(Tail, Symbol, TailResult).

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

    Выделим первые два символа строки. Если первый совпадает с искомым (буква «о») — второй символ нужно пропустить. Остальные символы обработаем рекурсивно, и к полученному результату добавим только первый отделенный символ.

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

    Я привел реализацию на SWI Prolog, однако, вы можете преобразовать строку в список символов и использовать этот код для Visual или Turbo Prolog. Однако можно и переписать его с использованием функции frontchar (фактически она разделяет строку на голову и хвост):

    remove_even_after_symbol("", _Symbol, ""):-!.
    remove_even_after_symbol(String, _Symbol, String):-
      frontchar(String, _SingleElement, ""), !.
    remove_even_after_symbol(String, Symbol, ResultString):-
      frontchar(String, Symbol, StringWithoutSymbol), !,
      frontchar(StringWithoutSymbol, B, Tail), 
      remove_even_after_symbol(Tail, Symbol, TailResult),
      frontchar(Tailresult, Symbol, ResultString).
    remove_even_after_symbol([A, B|Tail], Symbol, ResultString):-
      frontchar(String, A, StringWithoutA), !,
      frontchar(StringWithoutA, B, Tail), 
      remove_even_after_symbol(Tail, Symbol, TailResult),
      frontchar(Tailresult, B, TailResultWithB),
      frontchar(TailResultWithB, A, ResultString).
    

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