package scheme2.visitor; import scheme2.AListFW; import scheme2.IListAlgo; public class LastNElements implements IListAlgo { int _n; // the input index. /** * The input index is passed as the parameter to the constructor. */ public LastNElements (int n) { _n = n; } /** * @param host the Empty list. * @param input not used. * @return the Empty list if _n == 0, else throws an exception. */ public Object forEmpty (AListFW host, Object input) { //if n is 0 then request is valid. We should return empty list. if (_n == 0) { return host; } throw new IllegalArgumentException ("Empty list has no data!"); } /** * @param host a non-empty list. * @param input not used. * @return the part of the host list that contains the last n elements. * @exception IllegalArgumentException whenever _n > number of elements in the host list. */ public Object forNonEmpty (AListFW host, Object input) { /*first we skip the first n elements from the given list. We could check if n is greater than the length of the host list but that would be one pass by itself. If n is too big SkipN will throw the exception*/ AListFW skipN = (AListFW)(host.getRest ().execute (new SkipN (_n-1), null)); /*note that now we have a list of length Length(host)-n starting at skipN but we also have a list of length n starting at host and ending at skipN.*/ /*now we start traversing through the skipN list and we move the list of length n along with skipN. MoveInParallel returns the final list that we moved with skipN when skipN gets to the end*/ return skipN.execute (new MoveInParallel (host), null); /*this algorithm traverses through the original list once and does not create a copy of the list*/ } }