1. 对字符串的处理不需要增加原来字符串的空间
这种情况下,我们可以利用STL中copy_if的思想从字符串的第一个字符开始处理。首先定义2个指针src, dest全部指向输入字符串的第一个字符,然后用src遍历整个字符串。根据对字符串的不同处理,决定是将src指向的字符拷贝到dest,做一些处理后拷贝到dest,还是直接忽略继续处理下一个字符。
Ex 1. 将字符串中连续多个空格合并成一个空格
void combineSpace(string& s)
{
int src = 0, dest = 0;
while(src<s.size())
{
//如果遇到一个空格,拷贝这个空格,并且忽略所有接下来的空格
if(s[src] == ' ')
{
s[dest++] = ' ';
while(src < s.size() && s[src] == ' ')
{
++src;
}
}
else //否则直接拷贝src到dest
{
s[dest++] = s[src++];
}
}
s.resize(dest);
}
Ex 2. 给定两个字符串str1, str。把str2中出现的字符从str1中删除
void deleteCommon(string& str1, const string& str2)
{
stdext::hash_set<char> mySet;
for(int i=0; i<str2.size(); ++i)
{
mySet.insert(str2[i]);
}
int src = 0, dest = 0;
while(src < str1.size())
{
//如果src指向的字符不在str2中
if(mySet.find(str1[src]) == mySet.end())
{
str1[dest++] = str1[src++];
}
else
{
++src;
}
}
str1.resize(dest);
}
2. 对字符串的处理需要增加原来字符串的空间
这种情况下, 如果按照前面的方法,指针dest可能会超过src,从而将一些还没有处理的字符覆盖掉。所以,我们应该从字符串的末尾开始处理
Ex 1. 将字符串中的空格用%20替换
void replaceSpace(string& str)
{
//计算新的字符串需要多少空间
int numSpace = 0;
for(int i=0; i<str.size(); ++i)
{
if(str[i] == ' ')
++numSpace;
}
int newSize = str.size() + numSpace*2;
//定义从后往前的指针
int src = str.size()-1, dest = newSize - 1;
str.resize(newSize, ' ');
while(src >= 0)
{
//如果遇到空格,用%20替换
if(str[src] == ' ')
{
str[dest--] = '0';
str[dest--] = '2';
str[dest--] = '%';
--src;
}
else //否则直接拷贝src到dest
{
str[dest--] = str[src--];
}
}
}
Ex 2. 合并两个排好序的字符串 str1, str2。
void mergeStr(string& str1, const string& str2)
{
//定义src1,src2分别指向str1, str2的末尾
int src1 = str1.size()-1, src2 = str2.size()-1;
str1.resize(str1.size() + str2.size(), ' ');
//定义dest指向扩充后的str1的末尾
int dest = str1.size() - 1;
while(src1 >=0 && src2 >=0)
{
//复制src1和src2中较大的字符到dest
if(str1[src1] >= str2[src2])
{
str1[dest--] = str1[src1--];