[英]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.