面试中的字符串问题 (1)
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--];