为什么我不能第二次调用 std::mismatch 函数?

Why I can't call std::mismatch function for the second time?

本文关键字:mismatch 函数 std 调用 不能 第二次 为什么      更新时间:2023-10-16

我使用STL的mismatch函数来帮助我找到公共目录路径。在此过程中,我使用multimap::equal_range来获取相等元素的范围。

对于我的示例程序(请参阅参考资料),我得到了一个向量vPathWithCommonDir,其中填充了3个元素,如"C:/MyProg/Raw/","C:/MyProg/子集/MTSAT/"answers"C:/MyProg/子集/GOESW/",第一次迭代multimap mmClassifiedPaths时。然后,我将这个向量传递给FindCommonPath函数,并返回我想要的公共路径"C:/MyProg"。第二次循环时,不需要调用FindCommonPath函数,因为只有一个元素。第三次迭代时,我得到了一个向量vPathWithCommonDir,其中包含2个元素,即"D:/Dataset/Composite/"answers"D:/Dataset/Global/"。当我第二次调用与vPathWithCommonDir一起传递的FindCommonPath函数时,发生了致命错误。我无法解决这个问题。

你能帮帮我吗?非常感谢!

// 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 ) ;
}   

您必须确保在提供给mismatch的两个迭代器范围中至少有相同数量的项-它不做任何检查。

修复方法是在范围之间进行距离检查,并将较小的范围作为第一个范围,将较大的范围作为第二个范围。