Вы можете решить эту проблему путем переосмысления стратегии.
Во-первых, какие у вас базовые чехлы?
- Вы в конечном итоге с пустым списком в качестве входных данных
- Вы имеете
I > J
В обоих этих случаях, вы бы добавить пустой список в то, что у вас есть до сих пор, и называть это хорошо ,
Далее, каковы ваши крайние случаи, о которых вы беспокоитесь?
J
находится за пределами конца списка
I
есть до начала списка
В первом случае, вы просто пройти до конца списка ввода. Во втором вы начинаете в начале списка ввода.
Хорошо, давайте попробуем и реализуем это, я собираюсь использовать аккумулятор и обернуть его вызовом.
sublist(L1, L2, I, J):-
sublist(L1, Temp, I, J, []),
!,
reverse(Temp, L2).
Мы входной список L1
, переменная унифицировать как наш список L2
вывода, а индексы, I
и J
. Я использую cut
, так что мне не нужно беспокоиться о возврате назад для других решений и отменить его, потому что накопленный список построен в обратном порядке.
Давайте работать на базовых корпусах.
Пустой список в качестве входных данных, просто объедините аккумулятор с нашим выходным списком. На данный момент нас не интересуют индексы. Как оказалось, это также удовлетворяет краевому случаю, где J
находится за пределами списка. Поскольку в этот момент мы будем накапливать весь входной список в накопителе и все еще иметь значение J, оставшееся выше.
sublist([], L2, _I, _J, L2).
I> J, снова, объедините аккумулятор с нашим выходным списком. Мы больше не заботимся о списке входных данных.
sublist(_L1, L2, I, J, L2):-
I > J.
Теперь кромки.
J
за пределами конца списка было решено выше.
I
до начала списка, просто установите этот индекс в 0 и перейдите к нему.
sublist(L1, L2, I, J, L2):-
I < 0,
sublist(L1, L2, 0, J, L2).
Теперь нам просто нужно реализовать фактическую логику. Мы хотим только скопировать, начиная с правильного I
. Итак, давайте уменьшим I
и выбросим части входного списка, пока мы не доберемся туда, где хотим. Для того, чтобы конец индекса совпал, нам нужно также уменьшить J
. Таким образом, мы сохраняем одинаковое расстояние между индексами.
sublist([_L|Ls], L2, I, J, Acc):-
I > 0,
sublist(Ls, L2, I-1, J-1, Acc).
Мы, наконец, хотим, чтобы мы были. Итак, давайте начнем составлять список с элементами из списка ввода. Это продолжается до тех пор, пока мы не ударим по одному из наших базовых случаев. После чего аккумулятор возвращается в исходное предложение sublist
.
sublist([L|Ls], L2, I, J, Acc):-
sublist(Ls, L2, I, J-1, [L|Acc]).
Собираем все вместе мы в конечном итоге с:
sublist(L1, L2, I, J):-
sublist(L1, Temp, I, J, []),
!,
reverse(Temp, L2).
sublist([], L2, _I, _J, L2).
sublist(_L1, L2, I, J, L2):-
I > J.
sublist(L1, L2, I, J, L2):-
I < 0,
sublist(L1, L2, 0, J, L2).
sublist([_L|Ls], L2, I, J, Acc):-
I > 0,
sublist(Ls, L2, I-1, J-1, Acc).
sublist([L|Ls], L2, I, J, Acc):-
sublist(Ls, L2, I, J-1, [L|Acc]).
И мы можем проверить это следующим образом:
?- sublist([1,2,3,4,5], S, 0,3).
S = [1, 2, 3, 4].
?- sublist([1,2,3,4,5], S, -1,30).
S = [1, 2, 3, 4, 5].
?- sublist([1,2,3,4,5], S, 3,1).
S = [].
?- sublist([1,2,3,4,5], S, 3,3).
S = [4].
?- sublist([1,2,3,4,5], S, 3,4).
S = [4, 5].
А что не так с *, что у вас есть до сих пор *? Люди здесь не должны давать вам ответы, а скорее объяснения. – Rubens
@Rubens ой, извините, забыли включить. Второй предикат не работает. В настоящее время он нуждается в 'I' и' J', чтобы быть в списке. –