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;
}
}