На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Пролог списки , Пару вопросов
    Цитата Swetlana @

    ок, подождём я как всегда не успеваю ..... Сегодня ещё пойду уточню, может я не так понимаю эти два задания и не так говорю

    вот что у меня получилось

    ExpandedWrap disabled
      member(X, [X|_]):-!.
      member(X, [_|Y]):- member(X, Y).
       
      %из пустого списка повторы уже удалены
      del2([],[]).
      %если голова списка принадлежит хвосту, то отбрасываем её
      del2([H|T],T1):-
        member(H,T),!,
        del2(T,T1).
      %если голова списка не принадлежит хвосту, делаем ей головой целевого списка
      del2([H|T],[H|T1]):-
        del2(T,T1).
       
      general([], _, []).
      general([X|T], L2, [X|Z]):- member(X, L2), !, general(T,  L2, Z).
      general([_|T], L4, L2):- general(T, L4, L2), del2(L2, L3), L2=L3.


    Результат
    ExpandedWrap disabled
      ?- general([a,b,c,d], [b,d,e], R).
      R = [b, d].
       
      ?- general([a,a,b,c,d], [b,d,e], R).
      R = [b, d].
       
      ?- general([a,a,b,c,d], [a,b,d,e], R).
      R = [a, a, b, d].
       
      ?- general([a,a,b,c,d], [b,a,d,e], R).
      R = [a, a, b, d].


    Например последний, первый список имеет два a, а во втором только одна, т.е ответ у нас два a. Это не решает проблему
      Цитата xpoint @
      в списке S есть K последовательно идущих одинаковых эллементов, которые записывает например в E

      ExpandedWrap disabled
        kart([], K, E).
        kart([_], K, E).
        kart([X,Y|T], K, E):- X=Y, kart(T, K, E).
        kart([_|T], K, E):- kart(T, K, E).


      перебираем, а вот как в них определить K элементов по очереди и записать в E
        процедура cross возвращает пересечение двух списков,
        для тестового примера [2,5,2,5]

        ExpandedWrap disabled
          domains
          list = integer*
          predicates
          del(integer,list,list)
          member(integer,list)
          cross(list,list,list)
           
          goal
          cross([2,5,2,5,2,5],[2,2,3,5,5],L), write(L).
           
           
          clauses
          cross([],_,[]):-!.
          % голова первого списка принадлежит второму списку
          cross([H|T],L,[H|T1]):-
            member(H,L),!,
            del(H,L,L1),% удаляем элемент из второго списка
            cross(T,L1,T1).
          % голова первого списка не принадлежит второму списку
          cross([H|T],L,T1):-
            del(H,L,L1),
            cross(T,L1,T1).
           
           
          del(_,[],[]):-!.
          del(H,[H|T],T):-!.
          del(X,[H|T],[H|T1]):-
            del(X,T,T1).
           
          member(H,[H|T]):-!.
          member(X,[_|T]):-
            member(X,T).
          Элемент списка, который идёт подряд ровно K раз
          В тестовом примере это 5.

          ExpandedWrap disabled
            domains
            list = integer*
            predicates
            find(list,integer,integer)
            count(integer,list,integer)
             
            goal
            find([2,2,5,5,5,2],3,X), write(X).
             
            clauses
            %в пустом списке любой элемент идёт 0 раз
            count(_,[],0):-!.
            %заданный элемент не совпадает с головой списка, значит, идёт 0 раз
            count(X,[H|T],0):-
              X<>H,!.  
            %заданный элемент совпадает с головой списка
            count(H,[H|T],K):-
              count(H,T,M),
              K=M+1.
              
            find([H|T],K,H):-
              count(H,[H|T],K),!.
            find([_|T],K,Y):-    
              find(T,K,Y).
            Спасибо вам Света, мда совсем не так думаю, как надо. Вот и проблемы :(
              Потому что хотите в одном правиле сделать сразу и всё. А на Прологе так не пишут. Сделали чуть-чуть, а для всего остального вызываем вспомогательную процедуру.
              Например.
              Надо найти элемент, который в списке идёт K раз подряд. Элементов много. Поэтому проверим вначале для первого, будет ли он K раз повторяться. Как это проверить внутри правила? А внутри правила не надо ничего проверять, надо вызвать вспомогательную процедуру count, она и проверит.
              ExpandedWrap disabled
                find([H|T],K,H):-
                  count(H,[H|T],K),!.

              Если первый элемент списка не повторяется K раз, то удалим его. А для уменьшенного списка уже можно вызвать рекурсию.
              ExpandedWrap disabled
                find([_|T],K,Y):-    
                  find(T,K,Y).
                Вот вопрос на засыпку в одном файле может быть несколько задач, если например member уже был определён до этого и второй раз пытаешся определить :rolleyes:

                Добавлено
                Цитата Swetlana @
                Потому что хотите в одном правиле сделать сразу и всё. А на Прологе так не пишут. Сделали чуть-чуть, а для всего остального вызываем вспомогательную процедуру.
                Например.
                Надо найти элемент, который в списке идёт K раз подряд. Элементов много. Поэтому проверим вначале для первого, будет ли он K раз повторяться. Как это проверить внутри правила? А внутри правила не надо ничего проверять, надо вызвать вспомогательную процедуру count, она и проверит.
                ExpandedWrap disabled
                  find([H|T],K,H):-
                    count(H,[H|T],K),!.

                Если первый элемент списка не повторяется K раз, то удалим его. А для уменьшенного списка уже можно вызвать рекурсию.
                ExpandedWrap disabled
                  find([_|T],K,Y):-    
                    find(T,K,Y).

                Да да я привык что в c++ или на каком pascal всё сразу, а теперь вот пролог нужно изучать, и получается что я хочу от него всё сразу и без проблем

                Добавлено
                Хмм а вот этот пример что мы смотрели

                ExpandedWrap disabled
                  did([]).
                  did([_]).
                  did([X,Y|T]):- X =< Y, did(T).

                [/code]
                Как я понял проверяет например

                ExpandedWrap disabled
                  ?- did([4,18,2,100]).


                4=<18
                2=<100


                И получаем true
                По сути дела тут false, так как тут 18 не меньше чем 2 :whistle:

                Добавлено
                Иду подумаю, мне кажется тут что-то не трудное :)
                Сообщение отредактировано: xpoint -
                  Цитата
                  Вот вопрос на засыпку в одном файле может быть несколько задач, если например member уже был определён до этого и второй раз пытаешся определить :rolleyes:

                  Иногда 2 разных мембера нужно описывать.
                  member может быть детерминированный, с отсечением, который находит только первое вхождение элемента.
                  Может быть недетерминированный без отсечения, при возвратах будет поочерёдно все вхождения находить.
                  Если для одной задачи нужен member детерминированный, а для другой недетерминированный, то описывать два раза, назвать member и member1.

                  Добавлено
                  Цитата
                  Хмм а вот этот пример что мы смотрели

                  Здесь ошибка, сори.
                  Надо так
                  did([X,Y|T]):- X =< Y, did([Y|T]).
                  1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0743 ]   [ 14 queries used ]   [ Generated: 18.07.25, 01:37 GMT ]