剑指offer五:字符串之替换空格

字符串是由若干字符组成的序列,C/C++中每个字符都以字符'\0'作为结尾,这样我们就能很方便地找到字符串的最后尾部。但由于这个特点,每个字符串中都有一个额外字符的开销,稍不留神就会造成字符串的越界。比如下面的代码:

char str[10];
strcpy(str,"0123456789");

我们先声明一个长度为10的字符数组,然后把字符串“0123456789”复制到数组中。“0123456789”这个字符看起来只有10个字符,但实际上它的末尾还有一个'\0'字符,因此它的实际长度为11个字节。要正确复制该字符串,至少需要一个长度为11个字节的数组。

为了节省内存,C/C++把常量字符串放到单独的一个内存区域。当几个指针指向同一个常量字符串时,它们实际上会指向相同的内存地址。但用常量内存初始化数组,情况却有所不同。下面通过一个面试题来学习这一知识点。运行下面的代码,得到的结果是什么?

剑指offer五:字符串之替换空格

剑指offer五:字符串之替换空格

 剑指offer五:字符串之替换空格

 

替换空格

剑指offer五:字符串之替换空格

 剑指offer五:字符串之替换空格

 剑指offer五:字符串之替换空格

 剑指offer五:字符串之替换空格

 剑指offer五:字符串之替换空格

剑指offer五:字符串之替换空格

 

#include <iostream>
using namespace std;
//length是字符数组string的总容量
void replaceBlank(char string[], int length)
{
	if (string == NULL && length <= 0)
		return;
	int originalLength = 0;//字符串的实际长度
	int numBlank = 0;//空格的个数
	int i = 0;
	while (string[i] != '\0')
	{
		originalLength++;
		if (string[i] == ' ')
			numBlank++;
		i++;
	}
	int newLength = originalLength + numBlank * 2;//把空格替换成人“%20”之后的长度
	if (newLength > length)
		return;

	int indexOfOriginal = originalLength;
	int indexOfNew = newLength;

	while (indexOfOriginal >= 0)
	{
		if (string[indexOfOriginal] == ' ')
		{
			string[indexOfNew--] = '0';//先赋值再减减
			string[indexOfNew--] = '2';
			string[indexOfNew] = '%';
		}
		else
		{
			string[indexOfNew] = string[indexOfOriginal];
		}
		indexOfNew--;
		indexOfOriginal--;
	}
}
int main()
{
	char string[20] = "we are happy.";
	replaceBlank(string, 20);
	cout << string << endl;
}

剑指offer五:字符串之替换空格

 

剑指offer五:字符串之替换空格 

剑指offer五:字符串之替换空格 

剑指offer五:字符串之替换空格 上图展示的是新创建一个数组,本题的意思是将A2的数字全部添加在 A1上,即最后合并的数组还是A1,如果从前往后比较赋值的话,A1中后面的数字需要多次往后移动。所以可以借助上面替换空格的思想,从后往前比较赋值:

#include<iostream>
using namespace std;

void combineArray(int A[], int B[],int numA,int numB)
{
	int sumLength = numA + numB -1;
	numA--;numB--;
	while (1)
	{
		if (numA < 0)
		{
			while (numB >= 0)
			{
				A[sumLength] = B[numB];
				numB--; sumLength--;
			}
			break;
		}
		if (numB < 0)
		{
			while (numA >= 0)
			{
				A[sumLength] = A[numA];
				numA--; sumLength--;
			}
			break;
		}
		if (A[numA] >= B[numB])
		{
			A[sumLength] = A[numA];
			numA--;sumLength--;
		}
		else
		{
			A[sumLength] = B[numB];
			numB--;sumLength--;		
		}	
	}
}

 剑指offer五:字符串之替换空格