/* API Functions */ eParBalanceLine get_par_balance_in_line(char* szLine, unsigned int nLineLength, int* io_pCurlyBalance) { eParBalanceLine eBalanced = E_PAR_LINE_BALANCED; char arrPars[MAX_LINE_LENGTH]; int nParDepth = -1; int i = 0; int nCurrCharIndex = 0; int fIgnore = 0; /* When we are in the middle of a string, ignore chars */ int nCurlyBalance = 0; /* Make sure the line's length is ok */ if (nLineLength > MAX_LINE_LENGTH) { return E_PAR_LINE_ERROR; } else if (nLineLength == 0) { return E_PAR_LINE_BALANCED; } /* Go over the entire line and check for balancing */ for (i = nCurrCharIndex; (i < MAX_LINE_LENGTH) && (i < nLineLength); ++i) { /* Set the ignore flag as needed */ fIgnore = toggle_ignore(szLine[i]); /* Not in ignore mode */ if (!(fIgnore == 1)) { /* Check for parenthesis */ switch (szLine[i]) { /* An opening parenthesis */ case '{': { /* Count curly separately */ nCurlyBalance++; /* Continue to the rest of the handling normally */ } case '(': case '[': { /* Don't count these as valid if we already short of parenthesis */ if (nParDepth >= -1) { nParDepth = opening_parenthesis(szLine[i], arrPars, nParDepth); } break; } /* A closing parenthesis */ case '}': { /* Count curly separately */ nCurlyBalance--; /* Continue to the rest of the handling normally */ } case ')': case ']': { nParDepth = closing_parenthesis(szLine[i], arrPars, nParDepth); break; } default: break; } } } /* Line is unbalanced */ if (nParDepth != -1) { eBalanced = E_PAR_LINE_NOT_BALANCED; } /* Curly braces not balanced */ if (nCurlyBalance != 0) { eBalanced = E_PAR_LINE_NOT_BALANCED_CURLY; *io_pCurlyBalance += nCurlyBalance; } return eBalanced; }
/*! \param bp The balanced parentheses sequence for that the pioneers should be calculated. * \param block_size Size of the blocks for which the pioneers should be calculated. * \param pioneer_bitmap Reference to the resulting bit_vector. * \par Time complexity * \f$ \Order{n} \f$, where \f$ n=\f$bp.size() * \par Space complexity * \f$ \Order{2n + n} \f$ bits: \f$n\f$ bits for input, \f$n\f$ bits for output, and \f$n\f$ bits for a succinct stack. * \pre The parentheses sequence represented by bp has to be balanced. */ static ::libmaus::bitio::IndexedBitVector::unique_ptr_type calculatePioneerBitVector(::libmaus::bitio::BitVector const & bp, uint64_t const block_size) { ::libmaus::bitio::IndexedBitVector::unique_ptr_type Ppioneer_bitmap(new ::libmaus::bitio::IndexedBitVector(bp.size())); ::libmaus::bitio::IndexedBitVector & pioneer_bitmap = *Ppioneer_bitmap; IncreasingStack opening_parenthesis(bp.size()); uint64_t cur_pioneer_block = 0; uint64_t last_start = 0; uint64_t last_j = 0; uint64_t cur_block=0; uint64_t first_index_in_block=0; // calculate positions of findclose and findopen pioneers for(uint64_t j=0, new_block=block_size; j < bp.size(); ++j, --new_block) { if( !(new_block) ) { cur_pioneer_block = j/block_size; ++cur_block; first_index_in_block = j; new_block = block_size; } // opening parenthesis if( bp[j] ) { /*j < bp.size() is not neccecssary as the last parenthesis is always a closing one*/ /* if closing par immediately follows opening, skip both and carry on */ if( new_block>1 and !bp[j+1] ) { ++j; --new_block; } /* otherwise push opening par */ else { opening_parenthesis.push(j); } } else { uint64_t const start = opening_parenthesis.top(); opening_parenthesis.pop(); // if start is not in this block (i.e. far parenthesis) if( start < first_index_in_block ) { // same block as previous pioneer if( (start/block_size)==cur_pioneer_block ) { // erase previous pioneer pioneer_bitmap[last_start] = false; pioneer_bitmap[last_j] = false; } // set this pioneer pioneer_bitmap[start] = true; pioneer_bitmap[j] = true; cur_pioneer_block = start/block_size; last_start = start; last_j = j; } } } pioneer_bitmap.setupIndex(); return UNIQUE_PTR_MOVE(Ppioneer_bitmap); }