package lrs.visitor; import lrs.*; /** * Splits the host in half. The host gets the first n/2 elements, * and the other half gets the last n - n/2 elements. */ public class Splitter implements IAlgo { public final static Splitter Singleton = new Splitter (); private Splitter() { } /** * @param host * @param input * @return */ public Object emptyCase(LRStruct host, Object input) { return new LRStruct(); } /** * Asks the host's tail to split passing host as a potential "split point". * @param host * @param input not used * @return */ public Object nonEmptyCase(LRStruct host, Object input) { return host.getRest().execute(new Advance0(), host); } /** * "Quick and dirty" test. * @param args */ public static void main(String[] args) { LRStruct l1 = new LRStruct (); System.out.println ("l1: " + l1); System.out.println ("Splitting l1..."); LRStruct l2 = (LRStruct)l1.execute(Splitter.Singleton, null); System.out.println ("l1: " + l1); System.out.println ("l2: " + l2); l1.insertFront (new Integer (-9)); l1.insertFront (new Integer (15)); l1.insertFront (new Integer (263)); l1.insertFront (new Integer (-72)); l1.insertFront (new Integer (0)); System.out.println ("l1: " + l1); System.out.println ("Splitting l1..."); l2 = (LRStruct)l1.execute(Splitter.Singleton, null); System.out.println ("l1: " + l1); System.out.println ("l2: " + l2); l1.insertFront (new Integer (99)); l1.insertFront (new Integer (-55)); l1.insertFront (new Integer (12)); l1.insertFront (new Integer (48)); System.out.println ("l1: " + l1); System.out.println ("Splitting l1..."); l2 = (LRStruct)l1.execute(Splitter.Singleton, null); System.out.println ("l1: " + l1); System.out.println ("l2: " + l2); } } class Advance0 implements IAlgo { IAlgo advance1 = new IAlgo() { /** * We know the input is a potential split point and now we are at the end of * the original list. So we split right here at the split point. * @param host * @param accSplit * @return */ public Object emptyCase(LRStruct host, Object accSplit) { return cutAt((LRStruct)accSplit); } /** * Asks the host's tail to split passing input as a potential "split point". * @param host * @param accSplit a LRStruct. * @return */ public Object nonEmptyCase(LRStruct host, Object accSplit) { return host.getRest().execute(Advance0.this, accSplit); } }; /** * We know the input is a potential split point and now we are at the end of * the original list. So we split right here at the split point. * @param host * @param accSplit a LRStruct * @return */ public Object emptyCase(LRStruct host, Object accSplit) { return cutAt((LRStruct)accSplit); } /** * We have not reached the end yet, so we advance the accumlated split point * by one. * @param host * @param accSplit * @return */ public Object nonEmptyCase(LRStruct host, Object accSplit) { return host.getRest().execute(advance1, ((LRStruct)accSplit).getRest()); } /** * Cut off the list containing splitPoint at splitPoint. * Return a list that shares the same node with splitPoint. * @param splitPoint * @return */ private LRStruct cutAt(LRStruct splitPoint) { LRStruct tailHalf = new LRStruct (); tailHalf.execute (Becomes.Singleton, splitPoint); splitPoint.execute (Becomes.Singleton, new LRStruct ()); return tailHalf; } }