/* * Constructor #3 * * We know character probabilities. Input: pairs <character, probability> * * Here the alphabet is Huffman encoded. * * Note: all characters that will appear in the text must be included * in P. If in doubt, assign probability 0 (such characters will get * the longest codes) * */ alphabet_encoder(vector<pair<char_type,double> >& P){ sigma = P.size(); enc_type = huffman; auto comp = [](node x, node y){ return x.second < y.second; }; multiset<node,decltype(comp)> s(comp); //insert leaves for(auto it = P.begin();it!=P.end();++it) s.insert({{NULL,&it->first},it->second}); //Huffman algorithm while(s.size()>1){ //extract, copy and erase the 2 smallest elements auto min1 = new node(*s.begin()); s.erase(s.begin()); auto min2 = new node(*s.begin()); s.erase(s.begin()); double new_prob = min1->second + min2->second; pair<void*,void*> children = {min1,min2}; s.insert({ children, new_prob }); } node root = *s.begin(); extract_codes(&root,{}); root.free_memory(); }
bool NerveTool::extract_fiberitems( FILE *sout , StringList& fibersinfo , String type , String& value ) { // parse value: x,y -> x,y -> x,y ... ClassList<StringList> chain; value.trim(); while( !value.isEmpty() ) { String part; int idx = value.find( "->" ); if( idx < 0 ) { if( chain.count() == 0 ) return( false ); part = value; value.clear(); } else { part = value.getMid( 0 , idx ); value.remove( 0 , idx + 2 ); value.trim(); if( value.isEmpty() ) return( false ); } // parse part StringList *z = new StringList; chain.add( z ); if( !extract_codes( part , z ) ) { fprintf( sout , "wrong part=%s\n" , ( const char * )part ); return( false ); } // prohibit many-to-many if( z -> count() > 1 && chain.count() > 1 ) { StringList& zp = chain.getRef( chain.count() - 2 ); if( zp.count() > 1 ) return( false ); } } // chain of more than one if( chain.count() < 2 ) return( false ); // split chain int startChain = 0; int startChainCount = 0; for( int k = 0; k < chain.count(); k++ ) { StringList& z = chain.getRef( k ); int zn = z.count(); // starter if( k == 0 ) { startChainCount = zn; continue; } // many to one - split if( startChainCount > 1 ) { if( zn != 1 ) return( false ); addManyToOne( fibersinfo , type , chain.getRef( startChainCount ) , z.get( 0 ) ); startChain = k; startChainCount = zn; continue; } // allow x -> y -> z as is if( zn == 1 ) { if( k == chain.count() - 1 ) { addSingleChain( fibersinfo , type , chain , startChain , k ); break; } continue; } // x -> y -> x,y - split to x -> y and y -> x,y if( ( k - 1 ) > startChain ) { addSingleChain( fibersinfo , type , chain , startChain , k - 1 ); startChain = k - 1; startChainCount = 1; } addOneToMany( fibersinfo , type , chain.getRef( startChain ).get( 0 ) , z ); startChain = k; startChainCount = zn; } chain.destroy(); return( true ); }