2011-09-23 161 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

相关问题