好吧,它不是 Java,只是 JavaScript,但也许你可以转换它:
http://jsfiddle.net/BA8PJ/
function subWord( w, p, wrapL, wrapR ){
return w.substr(0,p)
+ ( wrapL ? (wrapL + w.substr(p,1) + wrapR ):'')
+ w.substr(p+1);
}
// wa = word array: ['apple','banana']
// wo = word object/lookup: {'apple':true,'banana':true}
function initLookup(){
window.wo = {};
for(var i=0; i < wa.length; i++) wo[ wa[i] ] = true;
}
function initialRandomWords(){
// choose some random initial words
var level0 = [];
for(var i=0; i < 100; i++){
var w = wa[ Math.floor(Math.random()*wa.length) ];
level0.push({ word: w, parentIndex:null, pos:null, leaf:true });
}
return level0;
}
function generateLevels( levels ){
while(true){
var nl = genNextLevel( levels[ levels.length-1 ]);
if( ! nl ) break;
levels.push( nl );
}
}
function genNextLevel( P ){ // P: prev/parent level
var N = []; // N: next level
var len = 0;
for( var pi = 0; pi < P.length; pi ++ ){
pw = P[ pi ].word; // pw: parent word
for( var cp = 0; cp < pw.length; cp++ ){ // cp: char pos
var cw = subWord( pw, cp ); // cw: child word
if( wo[cw] ){
len++;
P[ pi ].leaf = false;
N.push({ word: cw, parentIndex:pi, pos:cp, leaf:true });
}
}
}
return len ? N : null;
}
function getWordTraces( levels ){
var rows = [];
for( var li = levels.length-1; li >= 0; li-- ){
var level = levels[ li ];
for( var i = 0; i < level.length; i++ ){
if( ! level[ i ].leaf ) continue;
var trace = traceWord( li, i );
if( trace.length < 2 ) continue;
rows.push( trace );
}
}
return rows;
}
function traceWord( li, i ){
var r = [];
while(true){
var o = levels[ li ][ i ];
r.unshift( o );
i = o.parentIndex;
if( !i ) break;
li--;
if( li < 0 ) break;
};
return r;
}
function compareTraces( aa, bb ){
var a = aa[0].word, b = bb[0].word;
if( a == b ){
if( aa.length < bb.length ) return -1;
if( aa.length > bb.length ) return +1;
}
var len = Math.min( aa.length, bb.length )
for( var i = 0; i < len; i++ ){
var a = aa[i].word, b = bb[i].word;
if( a < b ) return +1;
if( a > b ) return -1;
}
if( aa.length < bb.length ) return -1;
if( aa.length > bb.length ) return +1;
return 0;
}
function prettyPrintTraces( rows ){
var prevFirstWord = null;
for( var ri = rows.length-1; ri >= 0; ri-- ){
var row = rows[ ri ];
if( prevFirstWord != row[0].word ){
if( prevFirstWord ) $('body').append('<div class="sep"/>');
prevFirstWord = row[0].word;
}
var $row = $('<div class="row"/>');
for( var i = 0; i < row.length; i++ ){
var w = row[i].word;
var c = row[i+1];
if( c ) w = subWord( w, c.pos, '<span class="cut">', '</span>');
var $word = $('<div class="word"></div>').html( w ).toggleClass('last-word', w.length < 2 );
$row.append( $word );
}
$('body').append( $row );
}
};
function main(){
initLookup();
window.levels = [ initialRandomWords() ];
generateLevels( levels );
rows = getWordTraces( levels );
rows.sort( compareTraces );
prettyPrintTraces( rows );
}