面试题三 替换空格
题目
请实现一个函数,把字符串中的每个空格替换成" %20 "。( 假定字符串未使用空间足够且只允许在原字符串上做替换 )
PS:括号内的说明未必会给出,这时候需要和考官进行沟通,了解他具体的需求。
差劲的思想
1. 编写一个移位函数,每次调用可将字符串的未处理部分往后移两个位置。
2. 遍历目标字符串,每当遇到空格则先调用1中函数一次,再将空格替换成%20,然后继续遍历。
分析
O(n²)的复杂度,显然不会让自己以及面试官满意。
如果能够在遍历的过程中,每次都将处理的字符移动到它最终的位置,那么复杂度就可降低到O(n)。对此,可以采用从后往前遍历的方法,设定两个指针,一个从最终生成字符串的最后一个位置向前遍历,一个从初始字符串的最后一个位置向前遍历。而最终生成字符串的最后一个位置是可以通过一次遍历而得出。
实现代码( 含测试 )
1 #include <iostream> 2 #include <stdio.h> 3 4 using namespace std; 5 6 // 字符串长度 7 #define MAX 100 8 9 // 字符串处理函数 10 bool convert(char array[]); 11 12 int main() 13 { 14 char array[MAX]; 15 16 cout << "请输入待测试字符串:" << endl; 17 gets(array); 18 19 if (convert(array)) 20 cout << endl << "转换成功!处理后字符串:" << array << endl; 21 else 22 cout << "处理异常!" << endl; 23 24 return 0; 25 } 26 27 bool convert(char array[]) 28 { 29 if (array == NULL) { 30 return false; 31 } 32 33 // 判断待处理字符串的实际长度 34 // 以及字符串中的空格个数 35 int count = 0; 36 int counts = 0; 37 char *p = array; 38 while (*p!='\0') { 39 if (*p == ' ') 40 counts++; 41 p++; 42 count++; 43 } 44 45 // 确定空间是否足够大 46 if ((count + counts*2) >= MAX) 47 return false; 48 49 // 定义两个遍历指针 50 char *p1 = p-1; 51 char *p2 = p; 52 53 // 找到结果字符串的最后位置 54 p2 = p+2*counts; 55 56 // 将结果字符串的末尾赋值为'\0' 57 *p2 = '\0'; 58 p2--; 59 60 // 两路指针一起遍历并作出处理 61 for (int i=0; i<count; i++) { 62 if (*p1 == ' ') { 63 *p2-- = '0'; 64 *p2-- = '2'; 65 *p2-- = '%'; 66 } 67 else 68 *p2-- = *p1; 69 p1--; 70 } 71 72 return true; 73 }
运行测试
小结
1. 字符串处理函数提高效率的关键往往是一次将字符移动到它最终的位置
2. 本题中两个指针同时遍历的思想值得思考