• 《C++ Primer》练习9.43-练习9.46:替换字符串简写和插入前后缀


    练习9.43

    练习9.43要替换字符串s中所有oldVal为newVal,要求使用迭代器和insert以及erase函数。
    在这里插入图片描述

    #include 
    #include 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    就从左往右遍历,不过字符串匹配也可以用kmp算法,这里应该还可以优化一下,不过可以用来熟悉一下语法。测试一下:

    在这里插入图片描述

    学习一下别人的写法:
    在这里插入图片描述

    • 使用了distance()函数
    • 使用了advance()函数
    • 使用了string{b2, e2}(b2,e2是迭代器)来得到子串
    • 使用了cbegin()cend()而不是begin()end()

    练习9.44

    练习9.44和9.43的目的一样,但是要求使用下标和replace进行替换。

    在这里插入图片描述
    按照同样的思路可以编写代码:

    #include 
    #include 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    输出结果同练习9.43

    学习一下别人的写法:
    在这里插入图片描述

    • 使用了substr()函数得到字符串的子串

    练习9.45

    练习9.45要将前缀和后缀加入名字,要求使用insert和append函数。

    在这里插入图片描述

    为了符合英文习惯,在生成的新的string里前缀和名字间、名字和后缀间加入了空格

    #include 
    #include 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    输出结果:
    在这里插入图片描述

    需要注意的是如果使用字符串的insert要插入的是字符(用单引号表示插入的元素),其使用迭代器插入的格式可以为

    s.insert(s.begin(), 'a');//在第一个元素前加入一个'a'
    s.insert(s.begin(), 5, 'a');//在第一个元素前加入5个'a'
    s.insert(s.begin(), {'b', 'a'});//在第一个元素前加入"ba"
    
    • 1
    • 2
    • 3

    不要写成(用双引号是错的):

    s.insert(s.begin(), "a");//在第一个元素前加入一个'a'?
    s.insert(s.begin(), 5, "a");//在第一个元素前加入5个'a'?
    s.insert(s.begin(), "ab");//在第一个元素前加入"ba"
    
    • 1
    • 2
    • 3

    而字符串的append可以往后直接插入双引号引起来的字符串:

    s.append(s.begin(), "ab");//在末尾添加一个字符串“ab”
    
    • 1

    练习9.46

    练习9.46和9.45的目的一样,但是要求只使用insert函数。

    在这里插入图片描述

    #include 
    #include 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    输出结果同练习9.45

    总结

    这几道题对于字符串迭代器是一个很好的练习,replace的迭代器移动还要多多注意。

    参考

    1. 《C++ Primer》345-347
  • 相关阅读:
    如何提高一个网站的排名?
    Linux 安装并搭建 3.10.7 RabbmitMQ 集群之搭建RabbitMq服务器(一)
    产品结构设计的主要内容有哪些?
    Cobalt Strike 注入msf会话
    Ubuntu系统-FFmpeg安装及环境配置
    K8S的安全机制
    异构数据库
    怎么理解flink的异步检查点机制
    安全基础 --- nodejs沙箱逃逸
    每日一题|2022-11-2|1620. 网络信号最好的坐标|暴力枚举|Golang
  • 原文地址:https://blog.csdn.net/subtitle_/article/details/133803212