Есть ли способ удалить последний элемент списка, не оставив точку выбора? [Дубликат]

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

5
задан repeat 15 August 2015 в 17:26
поделиться

4 ответа

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

list_butlast([X|Xs], Ys) :-                 % use auxiliary predicate ...
   list_butlast_prev(Xs, Ys, X).            % ... which lags behind by one item

list_butlast_prev([], [], _).
list_butlast_prev([X1|Xs], [X0|Ys], X0) :-  
   list_butlast_prev(Xs, Ys, X1).           % lag behind by one

Примеры запросов:

?- list_butlast([], Xs).
false.

?- list_butlast([1], Xs).
Xs = [].                                    % succeeds deterministically

?- list_butlast([1,2], Xs).
Xs = [1].                                   % succeeds deterministically

?- list_butlast([1,2,3], Xs).
Xs = [1,2].                                 % succeeds deterministically

Как насчет другого направления?

?- list_butlast(Xs, []).
Xs = [_A].

?- list_butlast(Xs, [1,2,3]).
Xs = [1,2,3,_A].

Как насчет наиболее общего запроса?

?- list_butlast(Xs, Ys).
   Xs = [_A]            , Ys = []
;  Xs = [_A,_B]         , Ys = [_A]
;  Xs = [_A,_B,_C]      , Ys = [_A,_B]
;  Xs = [_A,_B,_C,_D]   , Ys = [_A,_B,_C]
;  Xs = [_A,_B,_C,_D,_E], Ys = [_A,_B,_C,_D]
⋯
7
ответ дан repeat 17 August 2018 в 16:21
поделиться

Я считаю ваш анализ немного сложным. Начнем с базового случая:

without_last([_], []).

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

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

without_last([X|Xs], [X|WithoutLast]) :- 
    without_last(Xs, WithoutLast).

Это работает во всех направлениях.

?- without_last([1,2,3,4], X).
X = [1, 2, 3] ;
false.

?- without_last([1,2], X).
X = [1] .

?- without_last([1], X).
X = [] ;
false.

?- without_last([], X).
false.

?- without_last(X, [1,2,3]).
X = [1, 2, 3, _G294].

?- without_last([1,2,3,4], [1,2,3]).
true.

?- without_last([1,2,3,X], [1,2,3]).
true.
10
ответ дан Daniel Lyons 17 August 2018 в 16:21
поделиться

Реализация @ repeat является, безусловно, самой эффективной с текущими процессорами Prolog, но я все же предпочитаю использовать DCG для этой цели - тайно надеясь, что в один прекрасный день технология внедрения будет достаточно хороша, чтобы запустить ее с сопоставимой (пространственной) эффективностью.

list_butlast(Xs, Ys) :-
   phrase( ( seq(Ys), [_] ), Xs).

seq([]) -->
   [].
seq([E|Es]) -->
   [E],
   seq(Es).
5
ответ дан false 17 August 2018 в 16:21
поделиться

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

Без использования разреза:

deleteLastElement([_], []).
deleteLastElement([Head, Next|Tail], [Head|NTail]):-
  deleteLastElement([Next|Tail], NTail).

Первое предложение (базовый регистр) объединяет второй аргумент с пустым списком, когда в списке первых аргументов есть только один элемент.

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

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

deleteLastElement([Head|Tail], [Head|NTail]):-
  deleteLastElement(Tail, NTail).

И, конечно, вы также могли бы использовать append/3 для удаления последнего элемента из списка:

append(WithoutLast, [_], List).
7
ответ дан gusbro 17 August 2018 в 16:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: