package listFW.visitor;
import listFW.*;
/**
* Moves the minimum element from a list of Integer to the front.
* Uses SIDE-EFFECT to accumulate minimum: non-functional programming!!!
* @author Dung X. Nguyen
* @since Copyright: Copyright (c) 2005 by DXN - All rights reserved
*/
public class MinFront2 implements IListAlgo {
private Integer _accMin; // accumulated min.
private IListFactory _fact;
public MinFront2(IListFactory f) {
_fact = f;
}
public Object emptyCase(IEmptyList L, Object... inp) {
return L;
}
public Object nonEmptyCase(INEList L, Object... inp) {
// We assign _accMin the first of L as a candidate for minimum:
_accMin = (Integer)L.getFirst();
/**
* Let us consider the set S of all elements in L that precede L.
* S is clearly empty. At this point we have established the following:
* _accMin is an element of L and is smaller than all elements of S.
* We now call on an anonymous helper to operate on L in order to find
* the minimum and remove it from L. This helper will recursively
* traverse L to the end in order to obtain the minimum, save it in
* _accMin and reconstruct the host list L without the minimum on its way
* back from the recursive list traversal.
*/
IList withoutMin = (IList)L.execute(new IListAlgo() {
/**
* Note: when L executes this helper, this case is called since L is
* not empty. Thus for the first call to this method, h is L.
* We update _accMin to ensure that it is an element of L and is the
* minimum of all elements in L that precedes the rest of the host
* parameter h. Then we recursively call this helper on h.getRest()
* to save the minimum in _accMin and create a copy of h.getRest()
* that does not contain _accMin.
*/
public Object nonEmptyCase(INEList h, Object... nu) {
Integer first = (Integer)h.getFirst();
if (first < _accMin) {
_accMin = first;
}
/**
* At this point, we have established the following invariant:
* _accMin is an element of L and is the minimum of all elements
* in L that precedes h.getRest().
*/
IList accList = (IList)h.getRest().execute(this);
/**
* By induction, _accMin is now the minimum of the whole outer
* host list L, and accList is a copy of h.getRest() that does
* not contain _accMin.
*/
if (!first.equals(_accMin)) {
accList = _fact.makeNEList(first, accList);
}
// accList is now a copy of the host h without _accMin.
return accList;
/**
* As noted earlier, L.execute(...) calls nonEmptyCase() since
* L is not empty. Thus the first call to nonEmptyCase() is the
* call with L as the value for the host parameter h. So, when
* we return from this first call, accList is a copy of L without
* the minimum stored in _accMin.
*/
}
/**
* This method is only called from inside of the nonEmptyCase()
* method. The empty host parameter h marks the end of the outer
* host list L.
* _accmin is thus the minimum. The empty list is thus a copy of
* the outer host list L from the current list (empty) to the end
* that does not contain _accMin.
*/
public Object emptyCase(IEmptyList h, Object... nu) {
return h;
}
});
/**
* "Cons" the minimum to the front of the copy of the host that does not
* contain this minimum.
*/
return _fact.makeNEList(_accMin, withoutMin);
}
}