2010-10-23 1 views
0

Heres сниппет:список Рекурсия Append

translate("a", "4"). 
translate("m", "/\\/\\"). 

tol33t([], []). 
tol33t([Upper|UpperTail], [Lower|LowerTail]) :- 
    translate([Upper], [Lower]), 
    tol33t(UpperTail, LowerTail). 

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

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

Пример входных данных:

l33t ("был", Л). Он будет показан следующим образом: l33t ([119,97,115], L).

Теперь, когда должен вернуться, как: [92,47,92,47] ++ [52] ++ [53] или [92,47,92,47,52,53]

проблемы я не знаю, как добавить это так.

ответ

3

Рассмотрим эти изменения в tol33t/2:

tol33t([], []). 
tol33t([Code|Codes], Remainder) :- 
    translate([Code], Translation), !, 
    tol33t(Codes, Rest), 
    append(Translation, Rest, Remainder). 
tol33t([Code|Codes], [Code|Remainder]) :- 
    tol33t(Codes, Remainder). 

Первый пункт является базовым случаем.

Второе условие будет успешным тогда и только тогда есть перевод для текущего Code через translate/2, как список символов произвольной длины (Translation - обратите внимание, вы имели [Lower] вместо этого, что ограничивало результаты списков только длины 1). Вырез (!) после проверки перевода кода обязывает к поиску решения Rest рекурсивно, а затем присоединяет Translation к фронту, так как возвращается Remainder.

Третье предложение выполняется, если не было перевода для текущего Code (т. Е. Вызов translate/2) во втором предложении. В этом случае перевод для Code означает, что мы просто возвращаем его как есть и вычисляем остальное.

EDIT:

Если вы не резали (!), второй и третий пункты могут быть объединены, чтобы стать:

tol33t([Code|Codes], Remainder) :- 
    tol33t(Codes, Rest), 
    (translate([Code], Translation) ->    
     append(Translation, Rest, Remainder) 
    ; Remainder = [Code|Rest] 
    ). 

Это (неоптимизированная) версия проверяет, на каждом Code в списке персонажей, , если есть translate/2, который преуспевает; если да, то Translation прилагается к Rest, ещеCode передается без изменений. Обратите внимание, что это имеет ту же семантику, что и реализация выше, в том, что решения совершаются (например, имитируя разрез !), если антецедент до -> (translate/2) преуспевает. Обратите внимание, что сокращение в обеих реализациях строго необходимо; без него программа вернется к поиску решений, в которых привязки Code не переводятся, если существует применимое предложение translate/2.

+0

Я сделал что-то довольно близко к тому, что у вас там есть. Проблема в том, что я не могу использовать разрез, поэтому я все время зацикливаюсь – Matt

+0

На самом деле это должно быть нормально без проверки, чтобы увидеть, существует ли перевод. Благодаря! – Matt

+0

Aha ...если вы не можете использовать cut, вы можете использовать '->' вместо этого. Я добавлю код в редактирование. – sharky