2011-09-23 74 views
0

我使用STL的不匹配功能來幫助我找到公共目錄路徑。在這樣做的時候,我使用multimap :: equal_range來獲得相同元素的範圍。我得到了一個向量vPathWithCommonDir,裏面填充了3個元素,例如「C:/ MyProg/Raw /」,「C:/ MyProg/Subset/MTSAT /」和「 C:/ MyProg/Subset/GOESW /「,這是第一次迭代multimap mmClassifiedPaths。然後,我將這個向量傳遞給FindCommonPath函數,並返回了我想要的通用路徑「C:/ MyProg」。第二次循環時,不需要調用FindCommonPath函數,因爲只有一個元素。第三次迭代時,我得到了一個填充有2個元素(即「D:/數據集/複合/」和「D:/數據集/全局/」)的向量vPathWithCommonDir。當我第二次調用與vPathWithCommonDir一起傳遞的FindCommonPath函數時發生致命錯誤。我無法解決這個問題。爲什麼我不能再次調用std :: mismatch函數?

你能幫我嗎?非常感謝你!

// TestMismatch.cpp : Defines the entry point for the console application. 
// 
#include "stdafx.h" 

#include <algorithm> 
#include <map> 
#include <vector> 
#include <string> 

std::string FindCommonPath(const std::vector<std::string> & vDirList, char cSeparator) ; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
std::vector<std::string> vDirList; 

// Populate the vector list 
vDirList.push_back("C:/XML/"); 
vDirList.push_back("C:/MyProg/Raw/"); 
vDirList.push_back("C:/MyProg/Subset/MTSAT/"); 
vDirList.push_back("C:/MyProg/Subset/GOESW/"); 
vDirList.push_back("D:/Dataset/Composite/"); 
vDirList.push_back("D:/Dataset/Global/"); 
vDirList.push_back("E:/Dataset/Mosaic/"); 

std::multimap<std::string, std::string> mmClassifiedPaths; 

for (std::vector<std::string>::iterator it = vDirList.begin(); it != vDirList.end(); it++) 
{ 
    std::string sPath = *it; 
    std::string::iterator itPos; 

    std::string::iterator itBegin = sPath.begin(); 
    std::string::iterator itEnd = sPath.end(); 

    // Find the first occurrence of separator '/' 
    itPos = std::find(itBegin, itEnd, '/'); 

    // If found '/' for the first time 
    if (itPos != itEnd) 
    { 
     // Advance the current position iterator by at least 1 
     std::advance(itPos, 1); 

     // Find the second occurrence of separator '/' 
     itPos = std::find(itPos, itEnd, '/'); 

     // If found '/' for the second time 
     if (itPos != itEnd) 
     { 
      std::string sFound = sPath.substr(0, itPos - itBegin); 
      mmClassifiedPaths.insert(std::pair<std::string, std::string>(sFound, sPath)); 
     } 
    } 
} 

//std::multimap<std::string, std::string>::iterator it; 
std::vector<std::string> vPathToWatch; 
std::pair<std::multimap<std::string, std::string>::iterator, std::multimap<std::string, std::string>::iterator> pRet; 

for (std::multimap<std::string, std::string>::iterator it = mmClassifiedPaths.begin(); 
    it != mmClassifiedPaths.end(); it++) 
{ 
    size_t nCounter = (int)mmClassifiedPaths.count(it->first); 
    pRet = mmClassifiedPaths.equal_range(it->first); 

    if (nCounter <= 1) 
    { 
     vPathToWatch.push_back(it->second); 
     continue; 
    } 

    std::vector<std::string> vPathWithCommonDir; 

    for (std::multimap<std::string, std::string>::iterator itRange = pRet.first; itRange != pRet.second; ++itRange) 
    { 
     vPathWithCommonDir.push_back(itRange->second); 
    } 

    // Find the most common path among the passed path(s) 
    std::string strMostCommonPath = FindCommonPath(vPathWithCommonDir, '/'); 

    // Add to directory list to be watched 
    vPathToWatch.push_back(strMostCommonPath); 

    // Advance the current iterator by the amount of elements in the 
    // container with a key value equivalent to it->first 
    std::advance(it, nCounter - 1); 
} 

return 0; 
} 

std::string FindCommonPath(const std::vector<std::string> & vDirList, char cSeparator) 
{ 
std::vector<std::string>::const_iterator vsi = vDirList.begin(); 
int nMaxCharsCommon = vsi->length(); 
std::string sStringToCompare = *vsi; 

for (vsi = vDirList.begin() + 1; vsi != vDirList.end(); vsi++) 
{  
    std::pair<std::string::const_iterator, std::string::const_iterator> p = std::mismatch(sStringToCompare.begin(), sStringToCompare.end(), vsi->begin()); 

    if ((p.first - sStringToCompare.begin()) < nMaxCharsCommon)  
     nMaxCharsCommon = p.first - sStringToCompare.begin(); 
} 

std::string::size_type found = sStringToCompare.rfind(cSeparator, nMaxCharsCommon); 

return sStringToCompare.substr(0 , found) ; 
} 
+0

我會使用'std :: string&Path = *它;'//路徑只是一個方便的名字* it,不需要複製。另外,我不會使用'std :: advance(itPos,1);'(inefficient),只是寫'itPos = std :: find(++ itPos,itEnd,'/');' – MSalters

回答

1

你必須確保有在提供給mismatch兩個迭代器範圍至少儘可能多的項目 - 它沒有做任何檢查。

修復方法是在範圍之間進行距離檢查,並將較小的一個作爲第一個範圍,將較大的範圍作爲第二個範圍。

+0

謝謝Nim。你的建議可能是對的。我應該按照遞增的順序將按照各自長度傳遞給FindCommonPath的向量排序。 – GoldenLee

相關問題