剑指offer--面试题4
题目:替换字符串中的空格为“%20”。
说明:在浏览器的地址栏中输入某个网址,在解析过程中会看到类似“%20”的字样,这应该就是网络编程涉及的内容。。。
该题总体来说比较简单(连我都能想到!),个人认为考查的是思维的敏捷。
1、先按照自己的思路编程如下:
//以下为开辟新的存储单元,并在新的存储上执行替换O(n) #include "stdafx.h" #include <iostream> using namespace std; /*int main(int argc, char* argv[]) { char String[] = "We are happy."; char* str = String; char result0[30]; // char result0[] = "\0"; (会导致程序崩溃!) // 预先开辟结果的存储空间 char* result = result0; char* SubtituteString = "%20"; char* Subtemp = SubtituteString; while(*str != '\0') { if(' ' == *str) { while(*SubtituteString != '\0') { *result = *SubtituteString; SubtituteString++; result++; } str++; SubtituteString = Subtemp; } else { *result = *str; result++; str++; } } *result = '\0'; cout<<result0<<endl; return 0; }*/ //以下为本地替换O(n) int main(int argc, char* argv[]) { char String[30] = "We are happy."; int len = strlen(String); int i = 0, num = 0; //找空格总数O(n) while(i < len) if(String[i++] == ' ') num++; //最终字符串所占空间 int totallen = len+2*num; String[totallen] = '\0'; //由后向前移动字符 while(len) //O(n) { if(String[len-1] != ' ') String[--totallen] = String[--len]; //一步到位 else { String[--totallen] = '0'; String[--totallen] = '2'; String[--totallen] = '%'; --len; } } //减少移动次数 cout<<String<<endl; return 0; }
经过自己分析,无论本地替换还是开辟新的存储单元替换,时间复杂度都可以达到O(n).
看过作者的代码,自己写的代码无论从可读性、还是健壮性来说都存在差距!
1、变量命名上,尽量一眼看穿用途
2、无论指针还是数组名,因为都是地址,所以使用之前判空
3、当替换最后一个空格之后,两个指针会重合,此作为循环结束条件之一。
重写作者代码以加深印象:
//length为string字符数组的总容量 void ReplaceBlanks(char string[], int length) { if(string == NULL || length <=0) return; //originalLength为string[]的实际长度 int originalLength = 0; int numberOfblanks = 0; int i = 0; while(string[i] != '\0') { ++originalLength; if(string[i] == ' ') ++numberOfblanks; ++i; } //newLength为空格替换为"%20"后,字符串实际长度 int newLength = originalLength + 2 * numberOfblanks; //判断newLength是否过界 if(newLength > length) return; int indexOfOriginal = originalLength; int indexOfnew = newLength; while(indexOfOriginal >= 0 && indexOfnew > indexOfOriginal) { if(string[indexOfOriginal] == ' ') { string[indexOfnew--] = '0'; string[indexOfnew--] = '2'; string[indexOfnew--] = '%'; } else string[indexOfnew--] = string[indexOfOriginal]; indexOfOriginal--; } }
相关题目:有序数组A1,A2,且A1空间充足,要求:将A1,A2合并到A1且最终结果有序。
int main() { int Array1[20] = {1,2,13,19,22}; int Array2[5] = {3,4,21,35,78}; MergeSortedArray(Array1,Array2,5,5); return 0; } void MergeSortedArray(int Array1[], int Array2[], int size1,int size2) { //数组由小到大排列 //指针、大小判空 if(Array1 == NULL || Array2 == NULL || size1 == 0 || size2 == 0) return; // int TotalLength = size1+size2; int OutputLength = TotalLength; TotalLength--; int IndexOfArray1 = size1-1; int IndexOfArray2 = size2-1; while(IndexOfArray1>=0 && IndexOfArray2>=0) { if(Array1[IndexOfArray1] > Array2[IndexOfArray2]) { Array1[TotalLength--] = Array1[IndexOfArray1]; IndexOfArray1--; } else { Array1[TotalLength--] = Array2[IndexOfArray2]; IndexOfArray2--; } } //得到剩余数字的索引,分类讨论 if(IndexOfArray1 > IndexOfArray2) while(IndexOfArray1 >= 0 && TotalLength >=0) { Array1[TotalLength--] = Array1[IndexOfArray1]; IndexOfArray1--; } else while(IndexOfArray2 >= 0 &&TotalLength >=0) { Array1[TotalLength--] = Array2[IndexOfArray2]; IndexOfArray2--; } //输出排序后整个数组 for(int i=0; i<OutputLength; i++) cout<<Array1[i]<<','; cout<<endl; }
PS:程序仍有不少瑕疵。。。,自己可提升的空间太大了!!!
清醒时做事,糊涂时读书,大怒时睡觉,独处时思考; 做一个幸福的人,读书,旅行,努力工作,关心身体和心情,成为最好的自己
-- 共勉