标签:
感觉基本功还是不扎实,虽然能做些程序但是现在看来我还是个初学者(primer),试着完成习题结果还得修修改改。
废话不多说,实现功能很简单,《C++ Primer》9.5.2节习题。
// 将s中所有oldVal替换成newVal void replace(string& s, const string& oldVal, const string& newVal);
对字符串进行替换,实际上是先找到字符串s中的匹配部分,将匹配部分(oldVal)删除,然后插入要替换的字符串(newVal)
std::string的成员函数有很多重载形式,但总结下来是用两种方式表示区间:(pos, n)和(b, e)
都是左开右闭,前者是从pos开始的n个字符,后者则是两个迭代器之间的字符串。
因此关于进行匹配的字符串,可以用s.substr(pos, n)表示截取字符串,或者用string(b, e)来构造新的字符串。
要点1:由于是左开右闭,所以如果用迭代器遍历,用iter != s.end()来判断,会漏掉末尾。(比如用abc来替换ab时,字符串abcab会被变成abccab,而本该是变成abccabc)。
要点2:也不要用iter <= s.end()判断,因为循环语句内部的逻辑是,没找到匹配字符串时++iter,那么再次判断结束循环条件就会出问题。
(比如判断s.begin() + 1 + s.size() <= s.end(),相当于判断s.end() + 1 <= s.end())
总结上述要点,用迭代器遍历不能像下标遍历那样用<=来判断。
要点3:迭代器和下标的变化。如果没有匹配到字符串只需要自加就行,但是匹配到后,进行删除和插入后,无论是迭代器还是下标都是左开右闭的“开”这个位置,所以需要移到“闭”这个位置,以免无限循环。(比如把ab替换成abc后,应该从c后面一个字符开始查找,而不对位置做操作时会再在a的位置查找)
以上就是我试写程序时遇到的几个错误,下面贴代码。
第一题是用到std::string的insert和erase函数。我使用了迭代器遍历
// 使用迭代器及insert和erase将s中所有oldVal替换成newVal void replace(string& s, const string& oldVal, const string& newVal) { auto iter = s.begin(); size_t oldSize = oldVal.size(); size_t newSize = newVal.size(); while (iter + oldSize < s.end()) { if (string(iter, iter + oldSize) == oldVal) { iter = s.erase(iter, iter + oldSize); iter = s.insert(iter, newVal.cbegin(), newVal.cend()); iter += newSize; } else ++iter; } // 判断最后一个字符串是否等于oldVal if (string(iter, iter + oldSize) == oldVal) { s.erase(iter, iter + oldSize); s.insert(iter, newVal.cbegin(), newVal.cend()); } }
第二题是直接用replace函数。我使用了下标遍历。
void replace(string& s, const string& oldVal, const string& newVal) { size_t oldSize = oldVal.size(); size_t newSize = newVal.size(); string::size_type i = 0; while (i <= s.size() - oldSize) { if (s.substr(i, oldSize) == oldVal) { // 进行替换 s.replace(i, oldSize, newVal); // 更改当前位置 i += newSize; } else ++i; } }
要点4:每次进行替换字符串的长度会变化!
刚才我就是在这里出错,因为我直接用size_t len = s.size();然后循环条件就是 i <= len - oldSize,想要代码看起来更清晰,实际上忽略了这点。
补充点:string提供了compare函数来专门和一对(pos, n)进行比较
比如s.substr(i, oldSize) == oldVal可以改成!s.compare(i, oldSize, oldVal)或s.compare(i, oldSize, oldVal) == 0,截取的字符串仅仅是用来比较的话还是用compare比较好,substr会生成新的字符串。
要点5:compare在两者相等时返回0!即if (compare(...)) 表示如果比较两者不相等!
标签:
原文地址:http://www.cnblogs.com/Harley-Quinn/p/5405875.html