381 _BASE& model = *
this;
382 for (
auto i : model) {
384 mLeaveNodes.push_back(std::make_shared<node_type>(
i.second, _BASE::alphabet_type::getIndex(
i.first)));
390 for (
auto&
i : mLeaveNodes) {
391 mTreeNodes.insert(
i);
393 while (mTreeNodes.size() > 1) {
395 std::shared_ptr<node_type> combinedNode = std::make_shared<node_type>(*mTreeNodes.begin(), *++mTreeNodes.begin());
397 mTreeNodes.erase(mTreeNodes.begin());
398 mTreeNodes.erase(mTreeNodes.begin());
400 mTreeNodes.insert(combinedNode);
513 std::string node,
left,
right, parameters;
514 std::set<int> nodeIndices;
515 struct treeNodeConfiguration {
516 treeNodeConfiguration(
int _index,
int _left,
int _right) :
index(_index),
left(_left),
right(_right) {}
518 bool operator<(
const treeNodeConfiguration&
other)
const {
return index <
other.index; }
520 std::set<treeNodeConfiguration> treeNodeConfigurations;
522 std::map<int, int> leaveNodeMap;
523 while ((in.get(firstChar)) && firstChar !=
'\n' && (in.putback(firstChar)) && (in >> node) && (in >>
left) &&
524 (in >>
right) && ++lineNo >= 0) {
525 std::getline(in, parameters);
526 if (lineNo != std::stoi(node)) {
527 std::cerr <<
"format error: expected node no " << lineNo <<
", but got " << node <<
" (" <<
left <<
" " <<
right
528 <<
" " << parameters <<
")" << std::endl;
529 std::cerr <<
"Note: Huffman table dump has to be terminated by blank line or eof" << std::endl;
532 if (parameters.empty()) {
534 int leftIndex = std::stoi(
left);
535 int rightIndex = std::stoi(
right);
536 auto it = nodeIndices.find(leftIndex);
537 if (it == nodeIndices.end()) {
538 std::cerr <<
"Format error: can not find left child node with index " << leftIndex << std::endl;
541 nodeIndices.erase(it);
542 it = nodeIndices.find(rightIndex);
543 if (it == nodeIndices.end()) {
544 std::cerr <<
"Format error: can not find right child node with index " << rightIndex << std::endl;
547 nodeIndices.erase(it);
548 treeNodeConfigurations.insert(treeNodeConfiguration(lineNo, leftIndex, rightIndex));
551 typename _BASE::alphabet_type::value_type symbol;
553 typename _BASE::weight_type
weight;
555 int symbolIndex = _BASE::alphabet_type::getIndex(symbol);
557 if (mLeaveNodes.size() < symbolIndex + 1) {
558 mLeaveNodes.resize(symbolIndex + 1);
560 mLeaveNodes[symbolIndex] = std::make_shared<node_type>(
weight, symbolIndex);
561 std::stringstream ps(parameters);
562 uint16_t codeLen = 0;
566 mLeaveNodes[symbolIndex]->setBinaryCode(codeLen, code);
567 leaveNodeMap[lineNo] = symbolIndex;
568 _BASE::addWeight(symbol,
weight);
572 nodeIndices.insert(lineNo);
574 std::map<int, std::shared_ptr<node_type>> treeNodes;
575 for (
auto conf : treeNodeConfigurations) {
576 std::shared_ptr<node_type> left_local;
577 auto ln = leaveNodeMap.find(conf.left);
578 if (ln != leaveNodeMap.end()) {
579 left_local = mLeaveNodes[ln->second];
580 leaveNodeMap.erase(ln);
582 auto tn = treeNodes.find(conf.left);
583 if (tn == treeNodes.end()) {
584 std::cerr <<
"Internal error: can not find left child node with index " << conf.left << std::endl;
587 left_local = tn->second;
590 std::shared_ptr<node_type> right_local;
591 auto rn = leaveNodeMap.find(conf.right);
592 if (rn != leaveNodeMap.end()) {
593 right_local = mLeaveNodes[rn->second];
594 leaveNodeMap.erase(rn);
596 auto tn = treeNodes.find(conf.right);
597 if (tn == treeNodes.end()) {
598 std::cerr <<
"Internal error: can not find right child node with index " << conf.right << std::endl;
601 right_local = tn->second;
605 treeNodes[conf.index] = std::make_shared<node_type>(left_local, right_local);
607 if (leaveNodeMap.size() != 0 || treeNodes.size() != 1) {
608 std::cerr <<
"error: " << leaveNodeMap.size() <<
" unhandled leave node(s)"
609 <<
"; " << treeNodes.size() <<
" tree nodes(s), expected 1" << std::endl;
611 mTreeNodes.insert(treeNodes.begin()->second);