public static void compact ( Set < String > source , Adder adder , boolean shorterPairs , boolean moreCompact ) { if ( ! moreCompact ) { String start = null ; String end = null ; int lastCp = 0 ; int prefixLen = 0 ; for ( String s : source ) { if ( start != null ) { // We have something queued up if ( s . regionMatches ( 0 , start , 0 , prefixLen ) ) { int currentCp = s . codePointAt ( prefixLen ) ; if ( currentCp == 1 + lastCp && s . length ( ) == prefixLen + Character . charCount ( currentCp ) ) { end = s ; lastCp = currentCp ; continue ; } } // We failed to find continuation. Add what we have and restart adder . add ( start , end == null ? null : ! shorterPairs ? end : end . substring ( prefixLen , end . length ( ) ) ) ; } // new possible range start = s ; end = null ; lastCp = s . codePointBefore ( s . length ( ) ) ; prefixLen = s . length ( ) - Character . charCount ( lastCp ) ; } adder . add ( start , end == null ? null : ! shorterPairs ? end : end . substring ( prefixLen , end . length ( ) ) ) ; } else { // not a fast algorithm, but ok for now // TODO rewire to use the first (slower) algorithm to generate the ranges, then compact them from there. // first sort by lengths Relation < Integer , Ranges > lengthToArrays = Relation . of ( new TreeMap < Integer , Set < Ranges > > ( ) , TreeSet . class ) ; for ( String s : source ) { Ranges item = new Ranges ( s ) ; lengthToArrays . put ( item . size ( ) , item ) ; } // then compact items of each length and emit compacted sets for ( Entry < Integer , Set < Ranges > > entry : lengthToArrays . keyValuesSet ( ) ) { LinkedList < Ranges > compacted = compact ( entry . getKey ( ) , entry . getValue ( ) ) ; for ( Ranges ranges : compacted ) { adder . add ( ranges . start ( ) , ranges . end ( shorterPairs ) ) ; } } } }
Compact the set of strings .