繁体   English   中英

将while循环转换为do while循环

[英]Converting a while loop to a do while loop

这是一个函数,用父字符串中的另一个单词(strng)替换特定单词(字符串)的所有实例。

void clean(std::string &s,const std::string oldVal,const std::string newVal){
    std::string::size_type pos = 0;

    while((pos = s.find(oldVal,pos)) != std::string::npos){
        s.replace(pos,oldVal.size(),newVal);
        pos += newVal.size();
    }
}

我对C ++相当陌生,我发现while条件有些难以理解。 因此,我想到了使此代码更具可读性。 我试图使其变成do while循环。 但是,程序崩溃了。 抛出out_of_range异常。
我的代码有什么问题? 我使用相同的字符串来检查两个功能。

void clean2(std::string &s,const std::string oldVal,const std::string newVal){
    std::string::size_type pos = 0;
    do{
        pos = s.find(oldVal,pos);
        s.replace(pos,oldVal.size(),newVal);
        pos += newVal.size();
    }while(pos != std::string::npos);
}

这种情况

pos != std::string::npos

您必须在声明后检查

pos = s.find(oldVal,pos);

否则,您可以使用pos的无效值。

因此,在这种情况下,while循环比while循环看起来更好。

除了用while循环代替do-while循环外,您还可以使用for循环重写函数。 例如

void clean(std::string &s,const std::string oldVal,const std::string newVal)
{
    for ( std::string::size_type pos = 0; 
          ( pos = s.find( oldVal, pos ) ) != std::string::npos;
          pos += newVal.size() )
    {

        s.replace( pos, oldVal.size(), newVal );
    }
}

原因是while和do-while循环同时存在,这不仅是为了提高可读性。
主要区别在于检查条件的时间。
以前的版本按查找->测试->替换的顺序工作
您的版本按查找->替换->测试的顺序工作。

您可以做的是在替换之前添加一个if,以在尝试替换之前检查相同的循环条件。 但是,这与原始IMO相比效率较低且可读性较差。

您需要同时:

“找不到字符串时不调用替换”和“找不到字符串时不添加newVal.size()到pos”。 因此,如果在do-while循环内,则需要另一个

换一种说法:

void clean2(std::string &s,const std::string oldVal,const std::string newVal){
    std::string::size_type pos = 0;
    do{
        pos = s.find(oldVal,pos);
        if (pos != std::string::npos)
        {
            s.replace(pos,oldVal.size(),newVal);
            pos += newVal.size();
        }
    }while(pos != std::string::npos);
}

或者,您可以执行以下操作:

 while(true)
 {
     pos = s.find(oldVal,pos);
     if (pos != std::string::npos)
     {
         s.replace(pos,oldVal.size(),newVal);
         pos += newVal.size();
     }
     else 
     {
         break;
     }
 }

或同一主题的许多其他变体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM