剑指offer--替换空格
来源:互联网 发布:淘宝3c证书编号在哪里 编辑:程序博客网 时间:2024/06/15 17:28
记录《剑指offer》上的算法题。完整的代码例子可以在我的Github。
这是一道有关字符串的问题。首先在C/C++中,会把常量字符串放到单独的一个内存区域中,当几个指针赋值给相同的常量字符串时,它们实际上会指向相同的内存地址;但如果用常量内存初始化数组,数组的地址是不相同的。
下面给出替换空格的题目:
请实现一个函数,把字符串中的每个空格替换成”%20”。例如输入“We are happy.”, 则输出”We%20are%20happy.”。
在网络编程中,对于含有特殊字符的URL参数,如空格,”#“等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器可以识别的字符,替换的规则是在’%’后面跟上ASCII码的两位十六进制的表示。比如空格的ASCII码是32,即十六进制的0x20
,因此空格被替换成”%20”。
这里首先需要分两种情况,第一种是在原来的字符串上做替换;第二种是创建新的字符串并在新的字符串上做替换。现在假设是第一种情况,在原来的字符串上做替换并保证输入的字符串后面留有足够的空余内存。
最直观的做法是从头到尾扫描字符串,每一层碰到空格字符的时候做替换,由于需要将1个字符替换成3个字符,所以每次替换的时候,都要将空格后面的字符都往后移动两个字节,否则就有两个字符被替换了。因此,这种做法的时间复杂度是
上述做法是从前往后替换,现在可以换个思路,从后往前进行替换。首先是先遍历一遍字符串,计算字符串中空格的总数,由此计算出替换之后字符串的总长度,这里是每替换一个空格就需要增加两个字节的长度,因此替换之后的字符串长度应该是原来的长度加上两倍的空格数目。然后从后面开始复制和替换空格,需要准备两个指针P1和P2,P1指向当前字符串末尾,P2指向替换之后的字符串的末尾,然后向前移动P1,逐个把它指向的字符复制到P2指向的位置,而遇到空格的时候,P2就需要向前移动3格,因为需要复制过来的是3个字符,而P1还是移动一位。而当P2和P1都指向同一个位置的时候,说明所有空格都替换完毕了。
这种做法的时间复杂度是
#include<iostream>using std::cout;using std::endl;using std::cin;// 替换空格,length是字符数组string的总容量void ReplaceBlank(char string[], int length){ if (string == NULL || length <= 0){ return; } // 字符串string的实际长度 int originLength = 0; int numberOfBlank = 0; int i = 0; // 统计空格的数量和字符的数量 while (string[i] != '\0'){ ++originLength; if (string[i] == ' ') ++numberOfBlank; ++i; } // 替换空格后的字符串新长度 int newLength = originLength + numberOfBlank * 2; if (newLength > length) return; int indexOfOriginal = originLength; 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--; }}// 测试int main(void){ char str[10] = " hello"; char str2[10] = "he llo"; char str3[10] = "hello "; char str4[30] = "We are happy."; char str5[30] = "helloWorld."; char *str6 = NULL; char str7[10] = ""; char str8[10] = " "; char str9[20] = " "; // 空格位于字符串的最前面 cout << "origin: " << str; ReplaceBlank(str, 10); cout << ",--> " << str << endl; // 空格位于字符串的最后面 cout << "origin: " << str2; ReplaceBlank(str2, 10); cout << ",--> " << str2 << endl; // 空格位于字符串的中间 cout << "origin: " << str3; ReplaceBlank(str3, 10); cout << ",--> " << str3 << endl; // 字符串中有多个连续空格 cout << "origin: " << str4; ReplaceBlank(str4, 30); cout << ",--> " << str4 << endl; // 输入的字符串没有空格 cout << "origin: " << str5; ReplaceBlank(str5, 30); cout << ",--> " << str5 << endl; // 字符串是空指针 ReplaceBlank(str6, 10); // 字符串是空字符串 cout << "origin: " << str7; ReplaceBlank(str7, 10); cout << ",--> " << str7 << endl; // 字符串只有一个空格字符 cout << "origin: " << str8; ReplaceBlank(str8, 10); cout << ",--> " << str8 << endl; // 字符串中只有多个连续空格 cout << "origin: " << str9; ReplaceBlank(str9, 20); cout << ",--> " << str9 << endl; system("pause"); return 0;}
这种从后往前复制的思路还可以用在合并两个数组的情况。
- [剑指offer]替换空格
- [剑指offer]替换空格
- 剑指offer:替换空格
- 替换空格--《剑指offer》
- 剑指Offer:替换空格
- 【剑指offer】替换空格
- 《剑指Offer》--替换空格
- 剑指offer--替换空格
- 【剑指offer】替换空格
- 【剑指offer】空格替换
- 剑指offer-替换空格
- 剑指offer:替换空格
- [剑指offer]替换空格
- 《剑指offer》替换空格
- 剑指offer:替换空格
- 【剑指Offer】替换空格
- 【剑指offer】-替换空格
- 剑指offer 替换空格
- android过渡动画之makeSceneTransitionAnimation学习笔记
- com.mysql.jdbc.PacketTooBigException: Packet for query is too large
- <a>标签
- build failed with script: gradlew.bat :app:assembleDebug -P freelineBuild=true --stacktrace
- Ext数据模型
- 剑指offer--替换空格
- 脏读、不可重复读、幻读区别
- 【OpenCV入门教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑
- mysql 5.7.16 忘记root 密码 如何修改root密码
- slam收藏(updating)
- linux 获取文件名称并生成列表txt
- setTimeout和setInterval区别(更新中)
- Java读取property配置文件
- sap abap在表VBAP和VBAK上增加新字段的标准BAPI