проверка общих букв в определенном индексе в списке списков - PullRequest
0 голосов
/ 26 апреля 2020

Итак, у меня есть этот предикат letras_comuns(Lst,Common_ltrs), в котором Lst - это список слов, подобных [[a,n,o],[a,c,o],[a,t,o]], а Commons_ltrs - это результат общих букв во всех этих словах с определенным индексом.

Пример:

Lst_Pals = [[a,t,o], [a, c, o], [a,n,o], [a,l,o]], letras_comuns(Lst_Pals, Letras_comuns).
Lst_Pals = [[a,t,o], [a, c, o], [a,n,o], [a,l,o]],
Letras_comuns = [(1, a),(3, o)].

Что означает [(1, a), (3, o)]., так это то, что все слова имеют a в первом индексе и что все слова имеют o в 3-м индексе

Для этого я сделал этот знакомый предикат letras_comuns_aux(Lst,Letra_comum,Index)., в котором Lst такой же, как и раньше, Letra_comum - это общая буква во всех словах данного индекса, например, [(1, a)] и индексирование указанного индекса c.

Пример:

?- letras_comuns_aux([[a,t,o], [a, c, o], [a,n,o], [a,l,o]],Letra_comum,1).
Letra_comum = [(1, a)].

?- letras_comuns_aux([[a,t,o], [a, c, o], [a,n,o], [a,l,o]],Letra_comum,3).
Letra_comum = [(3, o)].

Таким образом, в основном это дает желаемый результат по заданному индексу, и этот предикат работает нормально, сказав, что я пытался сделать это для проверки все индексы в Lst.

Проблема в том, что по какой-то причине это дает бесконечный цикл, и я не понимаю, почему.

Программа:

letras_comuns_aux([],AC,_,_,AC) :- !.
letras_comuns_aux([P|R],Letra_comum,Index,El,_) :-
         nth1(Index,P,Ind_P),
         Ind_P == El,!,
         NAC = [(Index,El)],
         letras_comuns_aux(R,Letra_comum,Index,El,NAC).
letras_comuns_aux(_,Letra_comum,Index,El,_) :-
         NAC = [],!,
         letras_comuns_aux([],Letra_comum,Index,El,NAC).

letras_comuns(Lst_Pals, Letras_comuns) :-
   length(Lst_Pals,C),
   NC is C + 1,
   letras_comuns(Lst_Pals,Letras_comuns,[],NC,1).

letras_comuns(_, AC,AC,Comp,Comp).
letras_comuns(Lst_Pals, Letras_comuns,AC,Comp,Cont) :-
   letras_comuns_aux(Lst_Pals,Letra_comum,Cont),
   append(AC,Letra_comum,NAC),
   NCont is Cont +1,
   letras_comuns(Lst_Pals, Letras_comuns,NAC,Comp,NCont).

1 Ответ

1 голос
/ 26 апреля 2020

Это явно бесконечный l oop:

letras_comuns_aux(_,Letra_comum,Index,El,_) :-
         NAC = [],!,
         letras_comuns_aux([],Letra_comum,Index,El,NAC).

При каждом вызове NAC является переменной fre sh, которая, очевидно, будет связывать пустой список, а рекурсивный call затем получит такой пустой список как последний параметр. Какова цель этого?

Теперь простите мою лень, но понять вашу программу - явно больше работы, чем предложить более простой идиоматизм c способ:

letras_comuns(Lst_Pals, Letras_comuns) :-
    findall((L,I), foreach(member(X,Lst_Pals),nth1(I,X,L)), Letras_comuns).

Это дает

?- Lst_Pals = [[a,t,o], [a, c, o], [a,n,o], [a,l,o]],
|        letras_comuns(Lst_Pals, Letras_comuns).
Lst_Pals = [[a, t, o], [a, c, o], [a, n, o], [a, l, o]],
Letras_comuns = [(a, 1),  (o, 3)].

и становится возможным благодаря foreach / 2, который сохраняет привязки переменных между последовательными вызовами Generator.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...