为什么我无法第二次调用 std::mismatch 函数?

发布于 2024-12-06 06:36:04 字数 4255 浏览 1 评论 0原文

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

对于我的示例程序(请参见参考资料),我得到了一个向量 vPathWithCommonDir,其中填充了 3 个元素,例如“C:/MyProg/Raw/”、“C:/MyProg/Subset/MTSAT/”和“C:/MyProg” /Subset/GOESW/”,首次迭代多重映射 mmClassifiedPaths 时。然后我将此向量传递给 FindCommonPath 函数,并返回我想要的公共路径“C:/MyProg”。第二次循环时,不需要调用FindCommonPath函数,因为只有一个元素。第三次迭代时,我得到一个向量 vPathWithCommonDir ,其中填充了 2 个元素,即“D:/Dataset/Composite/”和“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 ) ;
}   

I use STL's mismatch function to help me to find common directory path. In doing so, I use multimap::equal_range to get range of equal elements.

For my sample program (please see fro you reference), I got a vector vPathWithCommonDir filled with 3 elements such as "C:/MyProg/Raw/", "C:/MyProg/Subset/MTSAT/" and "C:/MyProg/Subset/GOESW/", when iterating the multimap mmClassifiedPaths for the first time. I then passed this vector to FindCommonPath function, and returned a common path "C:/MyProg" what I wanted. When looping for the second time, it's not necessary to call FindCommonPath function because there is only one element. When iterating for the third time, I got a vector vPathWithCommonDir filled with 2 elements, namely "D:/Dataset/Composite/" and "D:/Dataset/Global/". A fatal error occurred when I called FindCommonPath function passed with vPathWithCommonDir for the second time. I could not solve this problem.

Would you please help me? Thank you very much!

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烙印 2024-12-13 06:36:04

您必须确保提供给 mismatch 的两个迭代器范围中至少有同样多的项目 - 它不执行任何检查。

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

You have to ensure that there are at least as many items in both iterator ranges provided to mismatch - it does not do any checking.

The fix would be to do a distance check between the ranges and provide the smaller one as the first range and the larger range as second.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文