/* * depth: the current depth of how much is sorted. * bound: how far to sort. */ void MediankeyBoundedQuicksort(unsigned char text[], UInt index[], UInt length, UInt low, UInt high, int depth, int bound, UInt maxChar, UInt *freq) { if (high - low <= 1) return; if (depth > bound) return; bool deleteFreq = false; if (freq == NULL) { UInt ci; maxChar = 0; for (ci = low; ci < high; ci++) { UInt c = text[index[ci]+depth]; if ( c > maxChar) { maxChar = c; } } freq = ProtectedNew<UInt>(maxChar+1); deleteFreq = true; } Nucleotide medianChar = ComputeMedianValue(text, index, length, low, high, depth, maxChar, freq ); UInt medianCharPos = FindFirstOf(text, index, low, high, depth, medianChar); UInt medLeft, lastLeft; UInt medRight, lastRight; // // Pack the median characters into the sides of the array. // SwapIndices(index[low], index[medianCharPos]); medLeft = lastLeft = low+1; medRight = lastRight = high-1; for(;;) { Nucleotide nuc; while(lastLeft <= lastRight and (nuc = text[index[lastLeft]+depth]) <= medianChar) { if (nuc == medianChar) { SwapIndices(index[medLeft], index[lastLeft]); medLeft++; } lastLeft++; } while(lastLeft <= lastRight and (nuc = text[index[lastRight]+depth]) >= medianChar) { if (nuc == medianChar) { SwapIndices(index[medRight], index[lastRight]); medRight--; } lastRight--; } if (lastLeft > lastRight) { // done with median sort. break; } // // Otherwise, this ends with an index at the left out of order // from the right assert(text[index[lastLeft]+depth] > text[index[lastRight]+depth]); SwapIndices(index[lastLeft], index[lastRight]); } // // Now join the indices of the median charactes in the middle of the // array. // // move left outside to middle UInt swapLeftLength = std::min(medLeft - low, lastLeft - medLeft); VecSwap(low, lastLeft - swapLeftLength, swapLeftLength, index); // move right outside to middle UInt swapRightLength = std::min(high - medRight - 1, medRight - lastRight); VecSwap(lastRight+1, high-swapRightLength, swapRightLength, index); UInt medianStartIndex = low + lastLeft - medLeft; UInt medianEndIndex = lastRight + (high - medRight); // Sort the suffices with keys lower than the median. // Since these may contain multiple keys that are less than the // median, the same depth is used. MediankeyBoundedQuicksort(text, index, length, low, medianStartIndex, depth, bound, maxChar,freq); if (medianEndIndex - medianStartIndex > 1) { MediankeyBoundedQuicksort(text, index, length, medianStartIndex, medianEndIndex, depth+1, bound, maxChar, freq); } MediankeyBoundedQuicksort(text, index, length, medianEndIndex, high, depth, bound, maxChar, freq); if (deleteFreq) {delete [] freq; freq = NULL;} }
int AString<B>::FindFirstOf(const tchar *s, int from) const { return FindFirstOf(strlen__(s), s, from); }