int selectIdx(ll *nums, int left, int right, int k) { int pivotIdx; if(left == right) return k; pivotIdx = medianOfMedians(nums, left, right); pivotIdx = partition(nums, left, right, pivotIdx); if(pivotIdx == left || k == pivotIdx) return k; else if(k < pivotIdx) return selectIdx(nums, left, pivotIdx - 1, k); else return selectIdx(nums, pivotIdx + 1, right, k); }
int medianOfMedians(ll *nums, int left, int right) { int numMedians, i, medianIdx, subLeft, subRight; numMedians = ((right - left) + 4) / 5; for(i = 0; i < numMedians; i++) { subLeft = left + i * 5; subRight = subLeft + 4; if(subRight > right) subRight = right; medianIdx = median_small(nums, subLeft, subRight); SWAP(nums[left+i], nums[medianIdx]); } return selectIdx(nums, left, left + numMedians - 1, left + numMedians / 2); }
/** \fn DIA_ocrGen \brief Dialog to select input & output files before calling the actual ocr engine */ uint8_t DIA_ocrGen(void) { vobSubParam subparam={NULL,0,0}; char *srtFileName=NULL; char *glyphFileName=NULL; admGlyph head(16,16); char *globalGlyph=NULL; uint32_t globalGlyphOn=0; ADM_OCR_SOURCE source; memset(&source,0,sizeof(source)); source.type=ADM_OCR_TYPE_VOBSUB; source.subparam=&subparam; prefs->get(FEATURE_GLOBAL_GLYPH_ACTIVE,&globalGlyphOn); if(globalGlyphOn) { prefs->get(FEATURE_GLOBAL_GLYPH_NAME,&globalGlyph); if(!*globalGlyph) { ADM_dezalloc(globalGlyph); globalGlyph=NULL; } } if(globalGlyph) { glyphFileName=globalGlyph; } _again: // Fist build a dialogFactory to get input and output files diaElemButton selectIdx(QT_TR_NOOP("Select idx file:"), cb_idx,&subparam,NULL); diaElemFile selectGlyph(1,&glyphFileName,QT_TR_NOOP("Use GlyphSet (optional):"), NULL, QT_TR_NOOP("Select GlyphSet file")); diaElemFile selectSrt(1,&srtFileName,QT_TR_NOOP("Output SRT file"), NULL, QT_TR_NOOP("Save SRT file")); diaElem *elems[]={&selectIdx,&selectSrt,&selectGlyph}; uint32_t n=3; if(globalGlyph) { n--; // Remove glyph from dialog } if(!diaFactoryRun(QT_TR_NOOP("Select input and ouput files"),n,elems)) { cleanupSub(&source); if(srtFileName )ADM_dezalloc(srtFileName); srtFileName=NULL; destroyGlyphTree(&head); return 0; } if(!ADM_fileExist(subparam.subname)) { GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist.")); goto _again; } if(!srtFileName || !*srtFileName) { GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Please Select a valid output SRT file.")); goto _again; } if(glyphFileName && *glyphFileName) { if(!ADM_fileExist(glyphFileName)) { GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("The idx/sub file does not exist.")); goto _again; } // Purge previous glyph set if any destroyGlyphTree(&head); uint32_t nb; printf("[OCR] Loading glyphset :<%s>\n",glyphFileName); if(!loadGlyph(glyphFileName,&head,&nb)) { GUI_Error_HIG(QT_TR_NOOP("File error"),QT_TR_NOOP("Cannot load the glyphset file.")); goto _again; } printf("[GLYPH] Found %u glyph\n"); } // We have our SRT and our idx/sub files : Go go go if(ADM_ocr_engine(source,srtFileName,&head)) { // Save glyph set if(globalGlyph) { uint32_t nb=1; saveGlyph(globalGlyph,&head,nb); } else { char *save=NULL; uint32_t nb=1; diaElemFile selectSave(1,&save,QT_TR_NOOP("GlyphSet filename"), NULL, QT_TR_NOOP("Save GlyphSet file")); diaElem *elems2[]={&selectSave}; if(diaFactoryRun(QT_TR_NOOP("Save Glyph"),1,elems2)) { saveGlyph(save,&head,nb); } if(save) ADM_dezalloc(save); } } cleanupSub(&source); if(srtFileName )ADM_dezalloc(srtFileName); srtFileName=NULL; destroyGlyphTree(&head); return 1; }
ll median(ll *nums, int n) { int idx = selectIdx(nums, 0, n - 1, n / 2); return nums[idx]; }