文章目录
- 练习9.43
- 练习9.44
- 练习9.45
- 练习9.46
- 总结
- 参考
练习9.43
练习9.43要替换字符串s中所有oldVal为newVal,要求使用迭代器和insert以及erase函数。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string &
replaceAbbreviation(string &s, string oldVal, string newVal)
{
for (auto iter = s.begin(); iter <= s.end() - oldVal.size(); ++iter)
{
auto olditer = oldVal.begin();
auto temp = iter;
while (olditer != oldVal.end() && *olditer == *iter)
{
olditer++;
iter++;
}
iter = temp;
if (olditer == oldVal.end())
{
iter = s.erase(iter, iter + oldVal.size());
iter = s.insert(iter, newVal.begin(), newVal.end());
iter = iter + newVal.size() - 1;//回到被插入元素的前一个位置,for循环++iter移到被插入元素继续替换,这里-1要注意
}
}
return s;
}
int main()
{
string s = "uuu";
string oldVal = "u";
string newVal = "auu";
cout << s << endl;
s = replaceAbbreviation(s, oldVal, newVal);
cout << s;
return 0;
}
就从左往右遍历,不过字符串匹配也可以用kmp算法,这里应该还可以优化一下,不过可以用来熟悉一下语法。测试一下:
学习一下别人的写法:
- 使用了
distance()
函数- 使用了
advance()
函数- 使用了
string{b2, e2}
(b2,e2是迭代器)来得到子串- 使用了
cbegin()
和cend()
而不是begin()
和end()
练习9.44
练习9.44和9.43的目的一样,但是要求使用下标和replace进行替换。
按照同样的思路可以编写代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string &
replaceAbbreviation(string &s, string oldVal, string newVal)
{
for (int i = 0; i <= s.size() - oldVal.size(); ++i)
{
int j = 0;
int temp = i;
while (j != oldVal.size() && s[i] == oldVal[j])
{
i++;
j++;
}
i = temp;
if (j == oldVal.size())
{
s.replace(i, oldVal.size(), newVal);
i += newVal.size() - 1;//记得把i移动回去,否则可能循环终止不了
}
}
return s;
}
int main()
{
string s = "uuu";
string oldVal = "u";
string newVal = "auu";
cout << s << endl;
s = replaceAbbreviation(s, oldVal, newVal);
cout << s;
return 0;
}
输出结果同练习9.43
学习一下别人的写法:
- 使用了substr()函数得到字符串的子串
练习9.45
练习9.45要将前缀和后缀加入名字,要求使用insert和append函数。
为了符合英文习惯,在生成的新的string里前缀和名字间、名字和后缀间加入了空格
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string &createNewString(string &s, string pre, string last)
{
s.insert(s.begin(), ' ');
s.insert(s.begin(), pre.begin(), pre.end());
s.append(" ");
s.append(last);
return s;
}
int main()
{
string s = "Mike";
string pre = "Mr.";
string last = "Jr.";
cout << s << endl;
s = createNewString(s, pre, last);
cout << s;
return 0;
}
输出结果:
需要注意的是如果使用字符串的insert要插入的是字符(用单引号表示插入的元素),其使用迭代器插入的格式可以为
s.insert(s.begin(), 'a');//在第一个元素前加入一个'a'
s.insert(s.begin(), 5, 'a');//在第一个元素前加入5个'a'
s.insert(s.begin(), {'b', 'a'});//在第一个元素前加入"ba"
不要写成(用双引号是错的):
s.insert(s.begin(), "a");//在第一个元素前加入一个'a'?
s.insert(s.begin(), 5, "a");//在第一个元素前加入5个'a'?
s.insert(s.begin(), "ab");//在第一个元素前加入"ba"
而字符串的append可以往后直接插入双引号引起来的字符串:
s.append(s.begin(), "ab");//在末尾添加一个字符串“ab”
练习9.46
练习9.46和9.45的目的一样,但是要求只使用insert函数。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string &createNewString(string &s, string pre, string last)
{
s.insert(0, " ");
s.insert(0, pre);
s.insert(s.size(), " ");
s.insert(s.size(), last);
return s;
}
int main()
{
string s = "Mike";
string pre = "Mr.";
string last = "Jr.";
cout << s << endl;
s = createNewString(s, pre, last);
cout << s;
return 0;
}
输出结果同练习9.45
总结
这几道题对于字符串迭代器是一个很好的练习,replace的迭代器移动还要多多注意。
参考
- 《C++ Primer》345-347