面试题8:字符串的空格处理
2016-03-22 09:34 Keiven_LY 阅读(1154) 评论(0) 编辑 收藏 举报一、字符串中的空格替换
题目描述:请实现一个函数,把字符串中的每个空格替换成“%20”。例如:输入“We are happy.",则输出”We%20are%20happy."
题记:
在网络编程中,如果URL参数中含有特殊字符,如空格、'#'等,可能导致服务器端无法获得正确的参数值。就需要将这些特殊字符转换成服务器可以识别的字符。转换规则是在'%'后面跟上ASCII码的两位十六进制的表示。如,空格的ASCII码是32,即十六进制的0x20,因此空格被替换成"%20";'#'的ASCII码为35,即十六进制的0x23,它在URL中被替换成"%23"。
解题分析:
原字符串中的一个空格字符,被替换后变成'%'、'2'、'0'这三个字符,即增加了两个字符,意思是:原字符串中若有m个空格,替换完成后,新的字符串就增加了m*2个字符。
在空间复杂度尽可能低的情况下,不允许开辟一个新的数组来存放替换空格后的字符串。如果从前往后替换字符串,那么保存在空格后面的字符串肯定会被覆盖。假设字符串的长度为n。对每个空格字符,需要移动后面O(n)个字符,因此对含有O(n)个空格字符的字符串而言总的时间复杂度是O(n2),明显不可取。
解题思路:
我们考虑从后往前进行替换,时间复杂度降为O(n)。
(1)首先遍历一遍字符串,找出字符串的长度以及其中的空格数
(2)根据原字符串的长度和空格数求出最后新的字符串的长度
(3)设置两个指针分别指向原字符串和新字符串的末尾位置
(4)如果原字符串的指针指向的内容不空,则将内容赋值给新指针指向的位置;否则从新指针开始向前赋值“02%”
(5)直到两个指针相等时表明字符串中的所有空格已经替换完毕
功能函数:
//将字符串str中的空格替换为"%20" void ReplaceBlank(char *str) { if(str==NULL) return; /******遍历字符串,求出其中空格的个数*****/ int nOldLength = 0; //计算原字符串的长度 int nCountBlank = 0; //计算原字符串的空格数 char *p = str; //指向数组首地址的指针 while (*p != '\0') { ++nOldLength; if (*p == ' ') ++nCountBlank; ++p; } int nNewLength = nOldLength + nCountBlank * 2;//新字符串的长度 int nOldIndex = nOldLength; int nNewIndex = nNewLength; while(nOldIndex != nNewIndex) { if (str[nOldIndex] != ' ') { str[nNewIndex--] = str[nOldIndex]; } else { str[nNewIndex--] = '0'; str[nNewIndex--] = '2'; str[nNewIndex--] = '%'; } --nOldIndex; } }
二、清空字符串中的空格
题目描述:请实现一个函数,把字符串中的每个空格清除。例如:输入“We are happy.",则输出”Wearehappy."
解题思路:
直接从头到尾进行清除。
(1)设置两个指针p1和p2初始状态都指向字符串的首字符
(2)若p2指向的元素不空,则将p2指向的内容赋给p1,然后都指向下一个元素;否则为空格,则p2指向下一元素。
(3)直到p2指向字符串末尾“\0”时清除空格结束。
功能函数:
//清除字符串str中的空格,从前往后遍历 void DeleteBlank(char *str) { if (str == NULL) { return; } char *p1 = str; char *p2 = str; while (*p1 != '\0')//注意此处应该是p1,不是p2,因为'\0'仍然需要赋给p1 { if (*p2 != ' ') { *(p1++) = *(p2++); } else { p2++; } } }
三、 清除字符串中多余的空格
题目描述:请实现一个函数,将给定的字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。例如输入“ We are happy. ”,则输出“We are happy.”
解题思路:
同样是从头往尾遍历,但需要定义一个bool变量标记是否保存一个空格。初始化时被设置为fasle,这样开始阶段的空格都不会被保存,当碰到一个非空格字符时,保存该字符,然后将标记设置为true,表示会保存字符串中的第一个空格。经过上述几步操作,可以保证字符串结尾要么是空字符,要么是非空格字符。如果是空格字符,则将其设置为"\0",如果不为空格字符,则在其后面加上"\0"。
功能函数:
//清除字符串str中多余的空格,从前往后遍历 void DeleteRedundantBlank(char *str) { if (str == NULL) return; char *p1 = str; char *p2 = str; bool keepBlank = false;//记录空格是否保存 while (*p1 != '\0')//注意此处应该是p1,不是p2,因为'\0'仍然需要赋给p1 { if (*p2 != ' ') { *(p1++) = *(p2++); keepBlank = true; } else { if (keepBlank) { *(p1++) = *(p2++); keepBlank = false; } else { p2++; } } } int nlen = strlen(str); if (str[nlen - 1] == ' ') { str[nlen - 1] = '\0'; } nlen = strlen(str); }
四、测试程序
头文件:
#include <iostream> using namespace std;
主函数:
int main() { cout<<"替换空格测试如下:"<<endl; cout<<"Test1:空格位于字符串中间的情况:"<<endl; char str1[50] = "We are happy."; ReplaceBlank(str1); cout << str1 << endl; cout<<"Test2:空格位于字符串的最前面、中间、最后面的情况:"<<endl; char str2[50] = " We are happy. "; ReplaceBlank(str2); cout << str2 << endl; cout<<"Test3:字符串是空字符串的情况:"<<endl; char str3[50] = ""; ReplaceBlank(str3); cout << str3 << endl; cout<<"Test4:只有连续多个空格的情况:"<<endl; char str4[50] = " "; ReplaceBlank(str4); cout << str4 << endl; cout<<endl; cout<<"清除空格测试如下:"<<endl; cout<<"Test1:空格位于字符串中间的情况:"<<endl; char str11[50] = "We are happy."; DeleteBlank(str11); cout << str11 << endl; cout<<"Test2:空格位于字符串的最前面、中间、最后面的情况:"<<endl; char str22[50] = " We are happy. "; DeleteBlank(str22); cout << str22 << endl; cout<<"Test3:字符串是空字符串的情况:"<<endl; char str33[50] = ""; DeleteBlank(str33); cout << str33 << endl; cout<<"Test4:只有连续多个空格的情况:"<<endl; char str44[50] = " "; DeleteBlank(str44); cout << str44 << endl; cout<<endl; cout<<"清除多余空格测试如下:"<<endl; cout<<"Test1:空格位于字符串中间的情况:"<<endl; char str111[50] = "We are happy."; DeleteRedundantBlank(str111); cout << str111 << endl; cout << strlen(str111) << endl; cout<<"Test2:空格位于字符串的最前面、中间、最后面的情况:"<<endl; char str222[50] = " We are happy. "; DeleteRedundantBlank(str222); cout << str222 << endl; cout << strlen(str222) << endl; cout<<"Test3:字符串是空字符串的情况:"<<endl; char str333[50] = ""; DeleteRedundantBlank(str333); cout << str333 << endl; cout<<"Test4:只有连续多个空格的情况:"<<endl; char str444[50] = " "; DeleteRedundantBlank(str444); cout << str444 << endl; system("pause"); return 0; }
测试结果: