您的位置:首页 > 编程语言 > C语言/C++

C++Primer第五版 9.5.2节练习

2015-09-18 07:29 423 查看
练习9.43:编写一个函数,接受三个string参数s,oldVal和newVal。使用迭代器及insert和erase函数将s中所有oldVal替换为newVal。测试你的程序,用它替换通用的简写形式,如,将“tho”替换为“though”,将“though”。

练习9.43(N)

/*
*练习9.43
*日期:2015/8/6
*问题描述:练习9.43:编写一个函数,接受三个string参数s,oldVal和newVal。使用迭代器及insert和erase函数将s中所有oldVal替换为newVal。测试你的程序,用它替换通用的简写形式,如,将"tho"替换为"though",将"thru"替换为"though"。

*说明:这道题写了N遍,参考了网上的,发现基本都或多或少存在问题 
*思路:1.分割单词,存入到一个容器 
       2.如果单词和oldVal相同,替换操作简单
       3.考虑oldVal是单词子串的情况,进行替换,这里参考了别人的写法,注意迭代器的位置 
*作者:Nick Feng  
*邮箱:nickgreen23@163.com 
*/

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

void find_replace(string s, string oldVal, string newVal)
{
    if (s.empty()||oldVal.empty()||newVal.empty())
    {
        cout << "s or oldVal or newVal字符串为空,请检查" << endl;
        return;
    }
    if (s.size() < oldVal.size())
    {
        cout << "目标字符串长度小于要查找的字符串" << endl;
        return;
    }

    string word;
    vector<string> vec;

    istringstream stream(s); //利用了流进行了单词分割 
    {
        while(stream >> word)
          vec.push_back(word);
    }

    vector<string>::iterator it = vec.begin();
    while(it != vec.end())
    {
         if(*it == oldVal)   //最想要的情况,正好这个单词就是要匹配的 
         {
            string::iterator iter = (*it).begin();
            iter=(*it).erase(iter, iter+oldVal.size());
            (*it).insert(iter,newVal.begin(),newVal.end());
         }

         else                 //比较不好的情况,在单词的子串里面找找看看 
        {
            string::iterator iter = (*it).begin();
            string::iterator oiter = oldVal.begin();
            while(iter != (*it).end())       //走到一个分支 
            {
                if(*iter == *oiter)            
                {
                   string substring = (*it).substr(iter - (*it).begin(), oldVal.size());
                   if(substring == oldVal)
                   {
                    unsigned offSet = iter - (*it).begin();                 
                    //这边参考 http://m.blog.csdn.net/blog/jierandefeng/38920947 
                    iter = (*it).erase(iter,iter+oldVal.size());
                    (*it).insert(iter,newVal.begin(),newVal.end());
                    iter = (*it).begin() + offSet + newVal.size() - 1; 
                   }
                }
                 ++iter;
            }

        }

          ++it;
    }

   for(auto i = 0; i != vec.size(); ++i)
     cout << vec[i] << " ";
     cout << endl;
}
int main()
{
    string s = "tho thogll thru athru AthruB";
    cout << s << endl;
    cout << "through replace tho" << endl;
    find_replace(s,"tho","though");
    cout << endl;

    cout << s << endl;
    string str = "thru th";
    cout << "through replace thru" << endl;
    find_replace(s,"thru","through");
    cout << endl;
    return 0;
}


练习9.44:重写上一题的函数,这次使用一个下标和replace。

练习9.44

/*
*练习9.44 
*2015/8/6 
*问题描述:练习9.44:重写上一题的函数,这次使用一个下标和replace。 
*说明:下面的if用于处理如 “I tho tho tho”,tho替换为though这种情况,大家不妨把那个if注视掉,测试一下,就会明白那个if的意图 
*作者:Nick Feng 
*邮箱:nickgreen23@163.com 
* 
*/

#include <iostream>
#include <string>

using namespace std;

void find_replace(string &s,string oldVal, string newVal)
{
   auto i = 0;
   while(i != s.size())
   {
     if(s[i] == oldVal[0])
     {
        string substring = s.substr(i,oldVal.size());
        if(substring == oldVal)
        {   
            if(newVal.size() > oldVal.size())                      
            //这边如果不作处理,在某些测试用例的情况下,有些子串会被覆盖掉,没有达到替换的效果
            {
               string temp="";                                          
               for(auto i = 0; i != newVal.size()-oldVal.size(); ++i)  //插入 newVal.size()-oldVal.size()个空格,保证替换时,不会发生覆盖的情况。 
                    temp = temp + " ";

               s.insert(i+oldVal.size(),temp);    
               //为替换之前,增加空格,让子串长度和newVal一样长,进行替换,不会覆盖原来的 
            }

            s.replace(i,newVal.size(),newVal);    
            //大家可以将上面的if注视掉,就知道怎么回事了,根源是,没replace,返回的是s的引用 
        }
     }
     ++i;
   }
}
int main()
{
    string str = "I tho tho athobtho";
    find_replace(str,"tho","though");
    cout << str << endl; 
    return 0;
}


练习9.45:编写一个函数,接受一个表示名字的string参数和两个分别表示前缀(如”Mr.”或MS.)和后缀(如“Jr”或“3”)的字符串。使用迭代器及Insert和append函数将前缀和后缀添加到给定的名字中,将生成的新string返回。

练习9.45

/*
*练习9.45 
*2015/8/6
*问题描述:练习9.45:编写一个函数,接受一个表示名字的string参数和两个分别表示前缀(如"Mr."或MS.)和后缀(如"Jr"或"3")的字符串。使用迭代器及Insert和append函数将前缀和后缀添加到给定的名字中,将生成的新string返回。
*说明:insert和append使用 
*作者:Nick Feng 
*邮箱:nickgreen23@163.com 
* 
*/

#include <iostream>
#include <string>

using namespace std;

void name_prefix_postfix(string &name, string prefix, string postfix) 
{
    name.insert(0,prefix);
    name.append(postfix);   
}

int main()
{
    string name = "Feng";
    name_prefix_postfix(name,"Mr.","ii");
    cout << name << endl;
    return 0;
}


练习9.46:重写上一题的函数,这次使用位置和长度来管理string,并只使用insert

练习9.46

/*
*练习9.46 
*2015/8/6
*问题描述:练习9.46:重写上一题的函数,这次使用位置和长度来管理string,并只使用insert 
*功能:insert 
*作者:Nick Feng 
*邮箱:nickgreen23@163.com 
* 
*/

#include <iostream>
#include <string>

using namespace std;

void name_prefix_postfix(string &name, string prefix,string postfix)
{
    name.insert(0,prefix);
    name.insert(name.size(),postfix);
}

int main()
{
    string name = "Feng";
    name_prefix_postfix(name,"Mr.","ii");
    cout << name << endl;
    return 0;
}


答:见练习9.43.cpp –练习9.46.cpp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: