Даны два списка и элемент. Выбрать элементы. Visual Prolog

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

Главная Форумы Программирование Помощь с решением задач на Prolog Задачи на списки Даны два списка и элемент. Выбрать элементы. Visual Prolog

Помечено: , , , , ,

В этой теме 2 ответа, 2 участника, последнее обновление  Nika 1 год, 5 мес. назад.

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

    Nika
    Участник

    Даны 2 списка, необходимо написать программу, которая по введенному с клавиатуры элементу списка 1 возвращает соответствующий по номеру элемент в списке 2.
    Эту задачу я решила, но как сделать, если в первом списке есть несколько элементов, соответствующих введенному элементу.. Необходимо вывести все соответствующие элементы из списка 2

    Есть код, который работает для списка 1 без повторяющихся элементов, если ввести повторы, то всё равно будет выводиться номер элемента только 1го вхождения. а надо, чтобы выводились номера всех нужных элементов.

    domains
      number = integer
      list = integer *
    predicates
      read_list (list)
      read_list2 (list)
      write_list (list)
      write_list2 (list)
      find_n (number, list)
      num(list,number,number)
      run
      %member(number,list)
    goal
      run.
    
    clauses
      run:-
        write("Введите элементы списка 1\n "),read_list(Lst),nl,
        write ("Введите элементы списка 2 \n"),read_list2(Lst2),nl,
        write ("Введите элемент из списка 1: "), readint(A),nl,
        num(Lst,A,N),
        write("Номер введенного элемента: "),nl,
        write(N), nl,
        write("элемент из списка 2, соответствующий по номеру из списка 1 : "),nl,
        find_n (N,Lst2),nl.
    
      read_list ([H|T]):-
        readint (H), !, read_list (T).
      read_list ([]).
    
      read_list2 ([H|T]):- 
        readint (H), !, read_list (T).
      read_list2 ([]).
    /*__________________________*/
    
      write_list ([]).
      write_list ([Head|Tail]):-
        write (Head), write (""), write_list (Tail).
    
      num([X|_],X,1).
      num([_|T],X,N):-
        num(T,X,N1),
        N=N1+1.
    /* ---------------------------------- */
    
    /* ------------------------------------ */
      find_n (Middle, [_|Tail]):-
        Middle1=Middle-1, Middle1>0,
        find_n (Middle1, Tail).
      find_n (_, [Head|_]):-
        write (Head),write (",").

  • #2453

    Вам нужно взять правило nth0 для поиска элемента на заданной позиции в списке. При этом если бы вы пользовались SWI Prolog — то решение заключалось бы в двух вызовах этого правила:

    solve(ListA, ListB, ElementA, ElementB):-
      nth0(Position, ListA, ElementA).
      nth0(Position, ListB, ElementB).

    В этом правиле инициализированными являются списки и ElementA. Первый вызов nth0 определит позицию этого элемента в ListA, а второй — выполнит поиска элемента на такой позиции в ListB. При этом, так как в прологе используется поиск с возвратами, подразумевающий полный перебор — то вывелись бы все решения (если в ListA несколько вхождений элемента — то соответствующие им значения были бы выбраны из ListB).

    Однако, сделать такую реализацию nth0, чтобы она работала в обе стороны (и выбирала элемент на заданной позиции, и и определяла позицию элемента в списке) — не так просто. Поэтому возьмите правило pos для определения позиции (по ссылке подробное описание его работы), за тем исключением, что в вашем случае оно должно быть недетерминированным (возвращать все возможные решения):

    pos(Element, [Element|_Tail], 0).
    pos(Element, [_Head|Tail], Index):-
      pos(Element, Tail, TailPos), 
      Index = TailPos + 1.

    Тогда решение запишется следующим образом:

    solve(ListA, ListB, ElementA, ElementB):-
      pos(ElementA, ListA, Position),
      nth0(Position, ListB, ElementB).

    Результаты работы программы на снимке экрана.

  • #2456

    Nika
    Участник

    Спасибо большое!

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