void CDictSetupDlg::SetActiveDict(int cur) { int cd; CStringArray list; GetDictList(list, cd); list.RemoveAt(0, RESERVED_DICTS); PutDictList(list, cur); }
void Cwhu_FaxSettingDlg::whu_AddAutoForArr(CStringArray &m_SorArr,CStringArray &m_AddArr) { int size = m_SorArr.GetSize(); CString m_FaxNum = m_AddArr.GetAt(0); int NumCount = 0; for (int i=0;i<size;i++) { CString m_str = m_SorArr.GetAt(i); if ((m_str == m_FaxNum)&&(i < size-1)) { CString m_str2 = m_SorArr.GetAt(i+1); int CharCount = m_str2.GetLength(); //字符串数组长度如果低于四,说明是来描述转发号码个数的标志位。//// if(CharCount<4) { int NumCount = _ttoi(m_str2); m_SorArr.RemoveAt(i,NumCount+2); break; } } } int m_AddSize = m_AddArr.GetSize(); if (m_AddSize>2) { m_SorArr.Append(m_AddArr); } }
bool CCSVFile::ReadData(CStringArray &arr) { // Verify correct mode in debug build ASSERT(m_nMode == modeRead); // Read next line CString sLine; int nValue = 0; int nColumn = 0; //统计数据列 bool bCheakCol = true; while (ReadString(sLine)) { if( !(sLine[0]>='0' && sLine.GetAt(0)<='9') ) //不读每行的首个字符不为数字的数据 continue; LPCTSTR p = sLine; while (*p != '\0') { CString s; // String to hold this value // Parse unquoted value while (*p != '\0' && *p != ',') { s.AppendChar(*p++); } // Advance to next character (if not already end of string) if (*p != '\0') p++; if (bCheakCol) { nColumn++; // 计算数据列数 } // Add this string to value array if (nValue < arr.GetCount()) arr[nValue] = s; else arr.Add(s); nValue++; } bCheakCol =false; } // Trim off any unused array values if (arr.GetCount() > nValue) arr.RemoveAt(nValue, arr.GetCount() - nValue); // We return true if ReadString() succeeded--even if no values return true; // Parse values in this line 需要给数据分列在此 }
bool CFileUtil::ScanDirectory( const CString &path,const CString &fileSpec, CStringArray &files, bool recursive/*=true*/, ScanDirectoryUpdateCallBack updateCB /*= NULL */ ) { CStringArray dirs; CString searchname; CFileFind find; files.RemoveAll(); dirs.Add(path); BOOL bRet; while(dirs.GetSize()>0) { if (dirs[0][dirs[0].GetLength()-1] == '\\') { searchname = dirs[0] + fileSpec; } else { searchname = dirs[0] + "\\" + fileSpec; } dirs.RemoveAt(0); bRet = find.FindFile (searchname,0); if(!bRet) { continue; } do { bRet = find.FindNextFile (); if(find.IsDots()) { //忽略.和..文件 continue; } if(find.IsDirectory ()) { //目录 files.Add(find.GetFilePath()); if (updateCB) { updateCB(find.GetFilePath()); } continue; } else { //文件,此处不处理 } }while(bRet) ; } return true; }
//Ham tim co so toi thieu roi nhau //Vao: aszX //Ra : aszY void Minimum(CStringArray& aszX, CStringArray& aszY ) { aszY.RemoveAll(); CStringArray aszTemp; int i; aszTemp.Append(aszX); while(aszTemp.GetSize()) { CString tempS1,tempS2,S1,S2,S3; tempS1 = aszTemp[0]; aszTemp.RemoveAt(0); for(i=0; i<aszTemp.GetSize(); i++) { S1 = Common(tempS1,aszTemp[i]); if(!S1.IsEmpty()) break; } if(i==aszTemp.GetSize())//Neu X,Y khong co thuoc tinh chung { if(!tempS1.IsEmpty()) aszY.Add(tempS1); } else { tempS2 = aszTemp[i]; aszTemp.RemoveAt(i); if(!S1.IsEmpty()) aszTemp.Add(S1); S2 = Sub(tempS1,tempS2); if((!S2.IsEmpty())&&(S2 != S1)) aszTemp.Add(S2); S3 = Sub(tempS2,tempS1); if((!S3.IsEmpty())&&(S3 != S1)&&(S3 != S2)) aszTemp.Add(S3); } } }
void Alpha(CStringArray& aszS) { int i=0; while(i<aszS.GetSize()) { CString tempS; Alpha(aszS[i],tempS); if(tempS.IsEmpty()) aszS.RemoveAt(i); else { aszS.SetAt(i,tempS); i++; } } }
/****************************************************************************** Function Name : OnBnClickedCbtnDissociate Input(s) : Output : Functionality : Call the functions to remove the selected Databases Member of : CDatabaseDissociateDlg Friend of : - Author(s) : Anish Kumar Date Created : 06.12.2006 Modifications : ******************************************************************************/ void CDatabaseDissociateDlg::OnBnClickedCbtnDissociate() { //TO store the path of files dissociated CStringArray aomStrFilesDissociated; CMainFrame* pMainFrame = (CMainFrame*)theApp.m_pMainWnd; // Get the indexes of all the selected items. int nCount = m_omDissociateDbLst.GetSelCount(); if(nCount > 0) { // Array of selected item's position CArray<int,int> aomListBoxSel; aomListBoxSel.SetSize(nCount); //Pass the array pointer to get the selected item's positions m_omDissociateDbLst.GetSelItems(nCount, aomListBoxSel.GetData()); aomStrFilesDissociated.RemoveAll(); for(int nTempCnt = 0 ; nTempCnt < nCount ; nTempCnt++) { BOOL bDBDeleted = FALSE; CString omstrDBPath ; //Selected file's index int nSelectedPos = aomListBoxSel.GetAt(nTempCnt); //Find the length of string to pass the buffer to have the selected File path int nBufferSize = m_omDissociateDbLst.GetTextLen(nSelectedPos); m_omDissociateDbLst.GetText(nSelectedPos,omstrDBPath.GetBuffer(nBufferSize)); bDBDeleted = (*(CMsgSignal**)(m_sDbParams.m_ppvImportedDBs))->bDeAllocateMemory(omstrDBPath.GetBuffer(0)); if(TRUE == bDBDeleted) { aomStrFilesDissociated.Add(omstrDBPath.GetBuffer(0)); } } //To remove from theApp class CStringArray aomstrDBFiles; (*(CMsgSignal**)(m_sDbParams.m_ppvImportedDBs))->vGetDataBaseNames(&aomstrDBFiles); //Delete the file path from the List box int nTotalCount = aomStrFilesDissociated.GetSize(); CString omStrTempFile; for(int nCount=0 ; nCount<nTotalCount ; nCount++) { omStrTempFile = aomStrFilesDissociated.GetAt(nCount); int nIndex = 0; if( (nIndex = m_omDissociateDbLst.FindString(0, omStrTempFile)) != LB_ERR ) { //Delete the file path from the list box m_omDissociateDbLst.DeleteString(nIndex); int nStoredFile = aomstrDBFiles.GetSize(); CString omStrTemp; BOOL bRemoved = FALSE; for(int nTemp = 0 ; nTemp < nStoredFile && bRemoved != TRUE; nTemp++) { omStrTemp = aomstrDBFiles.GetAt(nTemp); if(!(omStrTemp.Compare(omStrTempFile))) { aomstrDBFiles.RemoveAt(nTemp); bRemoved = TRUE; } } } } //Set the new file name array (*(CMsgSignal**)(m_sDbParams.m_ppvImportedDBs))->vSetDataBaseNames(&aomstrDBFiles); // Send a message to Tx Window about database change if( pMainFrame != NULL) { eUSERSELCTION eUserSel = eDATABASEIMPORTCMD; pMainFrame->m_objTxHandler.vPostMessageToTxWnd(WM_USER_CMD, (WPARAM)eUserSel,0); } ////Delete Signal watch list and Graph window list //// Check for Signal Watch & DLL load Condition // BOOL bUserOption = FALSE; if(pMainFrame->m_psSignalWatchList != NULL) { if(theApp.m_bFromAutomation == FALSE) bUserOption = AfxMessageBox(defIMPORT_WARNING, MB_YESNO | MB_DEFBUTTON1 | MB_ICONQUESTION) == IDYES; // If user wants to clear if(bUserOption == TRUE ) { // Clear Signal Watch List pMainFrame->vUpdateSWList(); } } //Added by Arun to update Data Handler Main entry list. //pMainFrame->vUpdateMainEntryListInWaveDataHandler(); //pMainFrame->vClearSignalInfoList(); //if(!pMainFrame->m_ouWaveTransmitter.bIsBlockEnabled()) // theApp.pouGetFlagsPtr()->vSetFlagStatus( SEND_SIGNAL_MSG, FALSE ); //Update Message windows pMainFrame->vUpdateAllMsgWndInterpretStatus(FALSE); // Check for Graph list for(register int nBusID = CAN; nBusID < AVAILABLE_PROTOCOLS; nBusID++) { if( pMainFrame->m_odGraphList[nBusID].m_omElementList.GetSize() > 0 ) { // Get the delete confirmation from the user if(theApp.m_bFromAutomation == FALSE) bUserOption = AfxMessageBox(defIMPORT_WARNING_GRAPH, MB_YESNO | MB_DEFBUTTON1 | MB_ICONQUESTION) == IDYES; // If user wants to clear if(bUserOption == TRUE ) { // Clear Graph List for all buses. for(register int nID = CAN; nID < AVAILABLE_PROTOCOLS; nID++) pMainFrame->m_odGraphList[nID].m_omElementList.RemoveAll(); // Send the Message to the Left View to Update List for all buses if( pMainFrame != NULL ) { pMainFrame->vPostConfigChangeCmdToSigGrphWnds(); } } break; } } } }
bool CPathUtilEx::RemoveDot(CString& strPathOrFile) { if (strPathOrFile.IsEmpty()) { return true; } else { strPathOrFile.Replace(_T('/'), _T('\\')); } //按照斜杠解析出每个文件夹名称 CStringArray strTempArray; int nStart = 0; for (int i=0; i<strPathOrFile.GetLength(); ++i) { if (strPathOrFile[i] == _T('\\')) //找到斜杠 { CString strTemp = strPathOrFile.Mid(nStart, i-nStart); if (!strTemp.IsEmpty()) { strTempArray.Add(strTemp); } nStart = i+1; } } if (strPathOrFile[strPathOrFile.GetLength()-1] != _T('\\')) { strTempArray.Add(strPathOrFile.Mid(nStart)); } //如果是点号直接去除,如果是两个点号去除上一个目录 for (int i=0; i<strTempArray.GetSize(); ++i) { if (strTempArray[i] == _T('.')) { strTempArray.RemoveAt(i); i--; } else if (strTempArray[i] == _T("..")) { if (i == 0) //第一个就..,认为是错误路径 { return false; } else { int nIndex = strTempArray[i-1].Find(_T(':')); if (nIndex != -1) //前一个是根盘符, 认为是错误路径 { return false; } else //去除两个点及前一个文件夹 { strTempArray.RemoveAt(i-1, 2); i -= 2; } } } else { continue; } } //将各部分按照斜杠连接起来 strPathOrFile = _T(""); for (int i=0; i<strTempArray.GetSize(); ++i) { strPathOrFile += strTempArray[i]; if (i < strTempArray.GetSize()-1) //最后一个不加斜杠 { strPathOrFile += _T('\\'); } } return true; }
void CWHTable::GetColumnStrings(CStringArray& csStrings, BOOL fKillUnsupportedTypes) { // Retrieve the strings in the current column. // Keep finding strings until an 'end choice' token is found. int nIndex = m_nIndex; int nTableItems = m_csaLine.GetUpperBound(); int nFound = 0; while (nIndex < nTableItems) { // Find the next non empty string in the column while (m_csaLine[nIndex].IsEmpty()) { IncrementRow(nIndex); if (nIndex > nTableItems) break; } // Add the non empty string to the array if (nIndex <= nTableItems) { // Add string BOOL f = AddFoundString(csStrings, nIndex); nFound++; // Check for an unsupported type if (fKillUnsupportedTypes && nFound > m_nTitleStrings) { int nLastIndex = csStrings.GetUpperBound(); CString cs = csStrings[nLastIndex]; // Search for a token int nBang = cs.Find(m_cListEnd); if (nBang != -1) { CString csProjType = cs.Right(cs.GetLength() - (nBang+1)); int nProjType = atoi((const char*)csProjType); // Take off the project type info cs = cs.Left(nBang); csStrings[nLastIndex] = cs; // See if the project type is supported CPmwApp* pApp = GET_PMWAPP(); CPmwDocTemplate* pTemplate = NULL; POSITION pos = pApp->GetFirstDocTemplatePosition(); while (pos != NULL) { CPmwDocTemplate* pThisTemplate = (CPmwDocTemplate*)pApp->GetNextDocTemplate(pos); if (pThisTemplate->ProjectType() == nProjType) { pTemplate = pThisTemplate; break; } } if (pTemplate == NULL) { // Take it off the list, and empty it csStrings.RemoveAt(nLastIndex); m_csaLine[nIndex].Empty(); // In theory, if this string was the last in the column, // we should put a m_cListEnd char in front of the next to // last string in the column because this one is now gone. // We don't really need to do this, however, because we're // tossing out project types which are in the first row. } } } IncrementRow(nIndex); if (f) break; } } }
/** * \brief initialises user selection * \return TRUE or FALSE * * This method will initialise user selection from * a configuration module to respective module. */ BOOL CCANMonitorApp::bInitialiseConfiguration(BOOL bFromCom) { BOOL bReturn = TRUE; CMainFrame* pMainFrame = static_cast<CMainFrame*> (m_pMainWnd); if(pMainFrame != nullptr ) { BOOL bIsDatabaseFoundInConfigFile = FALSE; if(m_pouMsgSignal != nullptr) { m_pouMsgSignal->bDeAllocateMemory(""); } else { m_pouMsgSignal = new CMsgSignal(sg_asDbParams[CAN], m_bFromAutomation); } if ( m_pouMsgSignal != nullptr ) { //Get the Database names CStringArray aomOldDatabases; //To keep all the files which are successfully imported CStringArray aomNewDatabases; aomNewDatabases.RemoveAll(); m_pouMsgSignal->vGetDataBaseNames(&aomOldDatabases); int nFileCount = aomOldDatabases.GetSize(); if(nFileCount == 0) { bIsDatabaseFoundInConfigFile = FALSE; // Reset corresponding flag m_pouFlags->vSetFlagStatus( SELECTDATABASEFILE, FALSE ); } else { CString omStrDatabase; int nDatabaseNotFound = 0; for(int nCount = 0; nCount < nFileCount; nCount++) { omStrDatabase = aomOldDatabases.GetAt(nCount); if (omStrDatabase.IsEmpty()) { nDatabaseNotFound++; aomOldDatabases.RemoveAt(nCount); --nCount; --nFileCount; } else { bIsDatabaseFoundInConfigFile = TRUE; // Check if the file really exists struct _finddata_t fileinfo; if (_findfirst(omStrDatabase.GetBuffer(MAX_PATH) ,&fileinfo) == -1L) { CString omStrMsg = _("Database File: "); omStrMsg += omStrDatabase; omStrMsg += _(" not found!"); if(bFromCom==FALSE) { MessageBox(nullptr,omStrMsg,"BUSMASTER",MB_OK|MB_ICONERROR); } // Remove the file name from configuration file. nDatabaseNotFound++; aomOldDatabases.RemoveAt(nCount); --nCount; --nFileCount; } else { // Reset corresponding flag m_pouFlags->vSetFlagStatus( SELECTDATABASEFILE, TRUE ); m_pouMsgSignal-> bFillDataStructureFromDatabaseFile(omStrDatabase, PROTOCOL_UNKNOWN); pMainFrame->vPopulateJ1939PGNList(); aomNewDatabases.Add(omStrDatabase); } } } if(nDatabaseNotFound > 0) { BYTE* pbyConfigData = nullptr; UINT unSize = 0; unSize += (sizeof (UINT) + ((sizeof(char) *MAX_PATH) * aomNewDatabases.GetSize())); pbyConfigData = new BYTE[unSize]; BYTE* pbyTemp = pbyConfigData; UINT nCount = 0; COPY_DATA(pbyTemp, &nCount, sizeof(UINT)); for (UINT i = 0; i < nCount; i++) { char acName[MAX_PATH] = { '\0' }; CString omDBName = aomNewDatabases.GetAt(i); strcpy_s(acName, MAX_PATH, omDBName.GetBuffer(MAX_PATH)); COPY_DATA(pbyTemp, acName, sizeof(char) * MAX_PATH); } CConfigData::ouGetConfigDetailsObject().bSetData(pbyTemp, unSize, SectionName[DATABASE_SECTION_ID]); delete[] pbyConfigData; pbyConfigData = nullptr; } if(aomNewDatabases.GetSize()== 0) { // Reset the flag and prompt user of file not in disk. m_pouFlags->vSetFlagStatus( SELECTDATABASEFILE, FALSE ); } } } else { if(bFromCom==FALSE) // Display a message and quit the application MessageBox(nullptr, _(MSG_MEMORY_CONSTRAINT), "BUSMASTER", MB_OK|MB_ICONINFORMATION); bReturn = FALSE; } //Finally load the default configuration pMainFrame->nLoadConfigFile(""); } return bReturn; }
BOOL COXEventLog::DeleteApplicationLog(LPCTSTR pszApplicationName) { ASSERT_VALID(this); ASSERT(pszApplicationName != NULL); if (pszApplicationName == NULL || lstrlen(pszApplicationName) <= 0) { m_ErrorCode = ERROR_INVALID_PARAMETER; return(FALSE); } COXRegistryItem regItem; CString log_key_name(_T("\\LocalMachine\\SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\")); log_key_name += pszApplicationName; log_key_name += _T("\\"); regItem.SetFullRegistryItem(log_key_name); if (regItem.Delete() == FALSE) { m_ErrorCode = regItem.GetLastError(); return FALSE; } /* ** Microsoft has a bug in this area. Even though we deleted the application from the ** HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\ ** registry area, they don't provide a way to delete the application from the ** HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Sources ** value. The application name is one of the strings in this REG_MULTI_SZ value. We ** still need to delete it from there. The names listed in this value appear in the ** "Source" combobox of the Event Viewer application View->Filter Events... menu selection. */ log_key_name = _T("\\LocalMachine\\SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"); regItem.SetFullRegistryItem(log_key_name); CStringArray sources; if (regItem.Open(FALSE) == FALSE || regItem.GetMultiStringValue(sources, _T("Sources")) == FALSE) { m_ErrorCode = regItem.GetLastError(); return FALSE; } int index = 0; int number_of_sources = PtrToInt(sources.GetSize()); BOOL application_was_found = FALSE; while(index < number_of_sources) { if (sources[index] == pszApplicationName) { application_was_found = TRUE; sources.RemoveAt(index); index = number_of_sources; } index++; } if (application_was_found != FALSE) { regItem.SetMultiStringValue(sources, _T("Sources")); } return TRUE; }
double CompareFunctions(FUNC_COMPARE_METHOD nMethod, CFuncDescFile *pFile1, int nFile1FuncNdx, CFuncDescFile *pFile2, int nFile2FuncNdx, BOOL bBuildEditScript) { CFuncDesc *pFunction1; CFuncDesc *pFunction2; CStringArray zFunc1; CStringArray zFunc2; double nRetVal = 0; CString strTemp; m_bEditScriptValid = FALSE; m_EditScript.RemoveAll(); if ((pFile1 == NULL) || (pFile2 == NULL)) return nRetVal; pFunction1 = pFile1->GetFunc(nFile1FuncNdx); pFunction2 = pFile2->GetFunc(nFile2FuncNdx); if ((pFunction1 == NULL) || (pFunction2 == NULL)) return nRetVal; pFunction1->ExportToDiff(zFunc1); pFunction2->ExportToDiff(zFunc2); if ((zFunc1.GetSize() == 0) || (zFunc2.GetSize() == 0)) return nRetVal; if ((bBuildEditScript) && (nMethod == FCM_DYNPROG_XDROP)) { // Note: XDROP Method currently doesn't support building // of edit scripts, so if caller wants to build an // edit script and has selected this method, replace // it with the next best method that does support // edit scripts: nMethod = FCM_DYNPROG_GREEDY; } switch (nMethod) { case FCM_DYNPROG_XDROP: { // // The following algorithm comes from the following source: // "A Greedy Algorithm for Aligning DNA Sequences" // Zheng Zhang, Scott Schwartz, Lukas Wagner, and Webb Miller // Journal of Computational Biology // Volume 7, Numbers 1/2, 2000 // Mary Ann Liebert, Inc. // Pp. 203-214 // // p. 205 : Figure 2 : "A dynamic-programming X-drop algorithm" // // T' <- T <- S(0,0) <- 0 // k <- L <- U <- 0 // repeat { // k <- k + 1 // for i <- ceiling(L) to floor(U)+1 in steps of 1/2 do { // j <- k - i // if i is an integer then { // S(i, j) <- Max of: // S(i-1/2, j-1/2) + mat/2 if L <= i-1/2 <= U and a(i) = b(j) // S(i-1/2, j-1/2) + mis/2 if L <= i-1/2 <= U and a(i) != b(j) // S(i, j-1) + ind if i <= U // S(i-1, j) + ind if L <= i-1 // } else { // S(i, j) <- S(i-1/2, j-1/2) // + mat/2 if a(i+1/2) = b(j+1/2) // + mis/2 if a(i+1/2) != b(j+1/2) // } // T' <- max{T', S(i, j)} // if S(i, j) < (T - X) then S(i, j) <- -oo // } // L <- min{i : S(i, k-i) > -oo } // U <- max{i : S(i, k-i) > -oo } // L <- max{L, k+1-N} <<< Should be: L <- max{L, k+1/2-N} // U <- min{U, M-1} <<< Should be: U <- min(U, M-1/2} // T <- T' // } until L > U+1 // report T' // // Given: // arrays: a(1..M), b(1..N) containing the two strings to compare // mat : >0 : Weighting of a match // mis : <0 : Weighting of a mismatch // ind : <0 : Weighting of an insertion/deletion // X = Clipping level : If scoring falls more than X below the // best computed score thus far, then we don't consider // additional extensions for that alignment. Should // be >= 0 or -1 for infinity. // // Returning: // T' = Composite similarity score // // For programmatic efficiency, all S indexes have been changed from // 0, 1/2 to even/odd and the i loop runs as integers of even/odd // instead of 1/2 increments: // // Testing has also been done and it has been proven that the order of // the two arrays has no effect on the outcome. // // In the following, we will define oo as DBL_MAX and -oo as -DBL_MAX. // // To hold to the non-Generalized Greedy Algorithm requirements, set // ind = mis - mat/2 // CStringArray &a = zFunc1; CStringArray &b = zFunc2; double Tp, T; double **S; int i, j, k, L, U; double nTemp; int M = a.GetSize(); int N = b.GetSize(); const double mat = 2; const double mis = -2; const double ind = -3; const double X = -1; // Allocate Memory: S = new double*[((M+1)*2)]; if (S == NULL) { AfxThrowMemoryException(); return nRetVal; } for (i=0; i<((M+1)*2); i++) { S[i] = new double[((N+1)*2)]; if (S[i] == NULL) AfxThrowMemoryException(); } // Initialize: for (i=0; i<((M+1)*2); i++) { for (j=0; j<((N+1)*2); j++) { S[i][j] = -DBL_MAX; } } // Algorithm: Tp = T = S[0][0] = 0; k = L = U = 0; do { k = k + 2; for (i = L+((L & 0x1) ? 1 : 0); i <= (U - ((U & 0x1) ? 1 : 0) + 2); i++) { j = k - i; ASSERT(i >= 0); ASSERT(i < ((M+1)*2)); ASSERT(j >= 0); ASSERT(j < ((N+1)*2)); if ((i&1) == 0) { nTemp = -DBL_MAX; if ((L <= (i-1)) && ((i-1) <= U)) { // TODO : Improve A/B Comparison: if (a.GetAt((i/2)-1).CompareNoCase(b.GetAt((j/2)-1)) == 0) { nTemp = __max(nTemp, S[i-1][j-1] + mat/2); } else { nTemp = __max(nTemp, S[i-1][j-1] + mis/2); } } if (i <= U) { nTemp = __max(nTemp, S[i][j-2] + ind); } if (L <= (i-2)) { nTemp = __max(nTemp, S[i-2][j] + ind); } S[i][j] = nTemp; } else { // TODO : Improve A/B Comparison: if (a.GetAt(((i+1)/2)-1).CompareNoCase(b.GetAt(((j+1)/2)-1)) == 0) { S[i][j] = S[i-1][j-1] + mat/2; } else { S[i][j] = S[i-1][j-1] + mis/2; } } Tp = __max(Tp, S[i][j]); if ((X>=0) && (S[i][j] < (T-X))) S[i][j] = -DBL_MAX; } for (L = 0; L < ((M+1)*2); L++) { if ((k - L) < 0) continue; if ((k - L) >= ((N+1)*2)) continue; if (S[L][k-L] > -DBL_MAX) break; } if (L == ((M+1)*2)) L=INT_MAX; for (U=((M+1)*2)-1; U>=0; U--) { if ((k - U) < 0) continue; if ((k - U) >= ((N+1)*2)) continue; if (S[U][k-U] > -DBL_MAX) break; } if (U == -1) U=INT_MIN; L = __max(L, k + 1 - (N*2)); U = __min(U, (M*2) - 1); T = Tp; } while (L <= U+2); // If the two PrimaryLabels at the function's address don't match, decrement match by 1*mat. // This helps if there are two are more functions that the user has labeled that // are identical except for the labels: if (pFile1->GetPrimaryLabel(pFunction1->GetMainAddress()).CompareNoCase( pFile2->GetPrimaryLabel(pFunction2->GetMainAddress())) != 0) Tp = __max(0, Tp - mat); // Normalize it: nRetVal = Tp/(__max(M,N)*mat); // Deallocate Memory: for (i=0; i<((M+1)*2); i++) delete[] (S[i]); delete[] S; } break; case FCM_DYNPROG_GREEDY: { // // The following algorithm comes from the following source: // "A Greedy Algorithm for Aligning DNA Sequences" // Zheng Zhang, Scott Schwartz, Lukas Wagner, and Webb Miller // Journal of Computational Biology // Volume 7, Numbers 1/2, 2000 // Mary Ann Liebert, Inc. // Pp. 203-214 // // p. 209 : Figure 4 : "Greedy algorithm that is equivalent to the algorithm // of Figure 2 if ind = mis - mat/2." // // i <- 0 // while i < min{M, N} and a(i+1) = b(i+1) do i <- i + 1 // R(0, 0) <- i // T' <- T[0] <- S'(i+i, 0) // d <- L <- U <- 0 // repeat // d <- d + 1 // d' <- d - floor( (X + mat/2)/(mat - mis) ) - 1 // for k <- L - 1 to U + 1 do // i <- max of: // R(d-1, k-1) + 1 if L < k // R(d-1, k) + 1 if L <= k <= U // R(d-1, k+1) if k < U // j <- i - k // if i > -oo and S'(i+j, d) >= T[d'] - X then // while i<M, j<N, and a(i+1) = b(j+1) do // i <- i + 1; j <- j + 1 // R(d, k) <- i // T' <- max{T', S'(i+j, d)} // else R(d, k) <- -oo // T[d] <- T' // L <- min{k : R(d, k) > -oo} // U <- max{k : R(d, k) > -oo} // L <- max{L, max{k : R(d, k) = N + k} + 2} <<< Should be: L <- max{L, max{k : R(d, k) = N + k} + 1} // U <- min{U, min{k : R(d, k) = M } - 2} <<< Should be: U <- min{U, min{k : R(d, k) = M } - 1} // until L > U + 2 // report T' // // Given: // arrays: a(1..M), b(1..N) containing the two strings to compare // mat : >0 : Weighting of a match // mis : <0 : Weighting of a mismatch // ind : <0 : Weighting of an insertion/deletion // (Satisfying: ind = mis - mat/2) // X = Clipping level : If scoring falls more than X below the // best computed score thus far, then we don't consider // additional extensions for that alignment. Should // be >= 0 or -1 for infinity. // S'(i+j, d) = (i+j)*mat/2 - d*(mat-mis) // or S'(k, d) = k*mat/2 - d*(mat-mis) // // Returning: // T' = Composite similarity score // // Testing has also been done and it has been proven that the order of // the two arrays has no effect on the outcome. // // In the following it will be assumed that the number of mismatches // (i.e. array bounds) can't exceed M+N since the absolute maximum // edit script to go from an array of M objects to an array of N // objects is to perform M deletions and N insertions. However, // these differences can be tracked either forward or backward, so // the memory will be allocated for the full search field. // // We are also going to define -oo as being -2 since no index can be // lower than 0. The reason for the -2 instead of -1 is to allow // for the i=R(d,k)+1 calculations to still be below 0. That is // to say so that -oo + 1 = -oo // CStringArray &a = zFunc1; CStringArray &b = zFunc2; double Tp; // T' = Overall max for entire comparison double Tpp; // T'' = Overall max for current d value double *T; double nTemp; int **Rm; int *Rvisitmin; // Minimum k-index of R visited for a particular d (for speed) int *Rvisitmax; // Maximum k-index of R visited for a particular k (for speed) int i, j, k, L, U; int d, dp; int dbest, kbest; int M = a.GetSize(); int N = b.GetSize(); const int dmax = ((M+N)*2)+1; const int kmax = (M+N+1); const int rksize = (kmax*2)+1; const double mat = 2; const double mis = -2; const double X = -1; const int floored_d_offset = (int)((X+(mat/2))/(mat-mis)); #define Sp(x, y) ((double)((x)*(mat/2) - ((y)*(mat-mis)))) #define R(x, y) (Rm[(x)][(y)+kmax]) // Allocate Memory: T = new double[dmax]; if (T == NULL) { AfxThrowMemoryException(); return nRetVal; } Rvisitmin = new int[dmax]; if (Rvisitmin == NULL) { AfxThrowMemoryException(); delete T; return nRetVal; } Rvisitmax = new int[dmax]; if (Rvisitmax == NULL) { AfxThrowMemoryException(); delete T; delete Rvisitmin; return nRetVal; } Rm = new int*[dmax]; if (Rm == NULL) { AfxThrowMemoryException(); delete T; delete Rvisitmin; delete Rvisitmax; return nRetVal; } for (i=0; i<dmax; i++) { Rm[i] = new int[rksize]; if (Rm[i] == NULL) AfxThrowMemoryException(); } // Initialize: for (i=0; i<dmax; i++) { T[i] = 0; Rvisitmin[i] = kmax+1; Rvisitmax[i] = -kmax-1; for (j=0; j<rksize; j++) { Rm[i][j] = -2; } } // Algorithm: i=0; // TODO : Improve A/B Comparison: while ((i<__min(M, N)) && (a.GetAt(i).CompareNoCase(b.GetAt(i)) == 0)) i++; R(0, 0) = i; dbest = kbest = 0; Tp = T[0] = Sp(i+i, 0); d = L = U = 0; Rvisitmin[0] = 0; Rvisitmax[0] = 0; /* printf("\n"); */ if ((i != M) || (i != N)) { do { d++; dp = d - floored_d_offset - 1; Tpp = -DBL_MAX; for (k=(L-1); k<=(U+1); k++) { ASSERT(d > 0); ASSERT(d < dmax); ASSERT(abs(k) <= kmax); i = -2; if (L < k) i = __max(i, R(d-1, k-1)+1); if ((L <= k) && (k <= U)) i = __max(i, R(d-1, k)+1); if (k < U) i = __max(i, R(d-1, k+1)); j = i - k; if ((i >= 0) && (j >= 0) && ((X<0) || (Sp(i+j, d) >= (((dp >= 0) ? T[dp] : 0) - X)))) { // TODO : Improve A/B Comparison: while ((i<M) && (j<N) && (a.GetAt(i).CompareNoCase(b.GetAt(j)) == 0)) { i++; j++; } R(d, k) = i; if (Rvisitmin[d] > k) Rvisitmin[d] = k; if (Rvisitmax[d] < k) Rvisitmax[d] = k; nTemp = Sp(i+j, d); Tp = __max(Tp, nTemp); /* printf("d=%2ld : k=%2ld, i=%2ld, j=%2ld, M=%2ld, N=%2ld, T=%2ld, Tp=%2ld, Tpp=%2ld", d, k, i, j, M, N, (int)nTemp, (int)Tp, (int)Tpp); */ if (nTemp > Tpp) { Tpp = nTemp; /* printf(" * Best (%2ld)", (int)Tpp); */ dbest = d; kbest = k; // Account for hitting the max M or N boundaries: if ((i != M) || (j != N)) { if (j > N) { kbest++; /* printf(" >>>>>> k++ j shift"); */ } else { if (i > M) { kbest--; /* printf(" <<<<<< k-- i shift"); */ } } } } /* printf("\n"); */ } else { R(d, k) = -2; if (Rvisitmin[d] == k) Rvisitmin[d]++; if (Rvisitmax[d] >= k) Rvisitmax[d] = k-1; } } T[d] = Tp; L = Rvisitmin[d]; U = Rvisitmax[d]; for (k=Rvisitmax[d]; k>=Rvisitmin[d]; k--) if (R(d, k) == (N+k)) break; if (k<Rvisitmin[d]) k = INT_MIN; L = __max(L, k+1); for (k=Rvisitmin[d]; k<=Rvisitmax[d]; k++) if (R(d, k) == M) break; if (k>Rvisitmax[d]) k = INT_MAX; U = __min(U, k-1); } while (L <= U+2); } // If the two PrimaryLabels at the function's address don't match, decrement match by 1*mat. // This helps if there are two are more functions that the user has labeled that // are identical except for the labels: if (pFile1->GetPrimaryLabel(pFunction1->GetMainAddress()).CompareNoCase( pFile2->GetPrimaryLabel(pFunction2->GetMainAddress())) != 0) Tp = __max(0, Tp - mat); // Normalize it: nRetVal = Tp/(__max(M,N)*mat); // Build Edit Script: if (bBuildEditScript) { int last_i, last_j; int cur_i, cur_j; int k_rest; if (dbest > 0) { m_EditScript.SetSize(dbest); k = kbest; last_i = M+1; last_j = N+1; /* printf("\n%s with %s:\n", LPCTSTR(pFunction1->GetMainName()), LPCTSTR(pFunction2->GetMainName())); */ for (d=dbest-1; d>=0; d--) { i = __max((R(d, k-1) + 1), __max((R(d, k) + 1), (R(d, k+1)))); /* printf("(%3ld, %3ld) : %3ld(%5ld), %3ld(%5ld), %3ld(%5ld) :", d, k, (R(d, k-1) + 1), (int)Sp((R(d, k-1))*2-k+1, d), (R(d, k) + 1), (int)Sp((R(d, k))*2-k, d), (R(d, k+1)), (int)Sp((R(d, k+1))*2-k-1, d)); for (j=Rvisitmin[dbest-1]; j<=Rvisitmax[dbest-1]; j++) { if (j == k-1) printf("("); else printf(" "); if (R(d,j)<0) printf(" "); else printf("%3ld", R(d, j)); if (j == k+1) printf(")"); else printf(" "); } printf("\n"); */ j = i-k; if (i == (R(d, k-1) + 1)) { strTemp.Format("%ld>%ld", i-1, j); cur_i = i-1; cur_j = j; k--; k_rest = 1; } else { if (i == (R(d, k+1))) { strTemp.Format("%ld<%ld", i, j-1); cur_i = i; cur_j = j-1; k++; k_rest = -1; } else { // if (i == (R(d, k) + 1)) strTemp.Format("%ld-%ld", i-1, j-1); cur_i = i-1; cur_j = j-1; // k=k; k_rest = 0; } } m_EditScript.SetAt(d, strTemp); // The following test is needed since our insertion/deletion indexes are // one greater than the stored i and/or j values from the R matrix. // It is possible that the previous comparison added some extra // entries to the R matrix than what was really needed. This will // cause extra erroneous entries to appear in the edit script. // However, since the indexes should be always increasing, we simply // filter out extra entries added to the end that don't satisfy // this condition: if ((k_rest == 0) && ((cur_i == last_i) && (cur_j == last_j))) { m_EditScript.RemoveAt(d); } last_i = cur_i; last_j = cur_j; } } // Note: if the two are identical, array stays empty: m_bEditScriptValid = TRUE; } // Deallocate Memory: delete[] T; delete[] Rvisitmin; delete[] Rvisitmax; for (i=0; i<dmax; i++) delete[] (Rm[i]); delete[] Rm; } break; } return nRetVal; }