一、替換空格
請實現一個函數,把字符串中的每個空格替換成“%20”。例如輸入“We are happy.",則輸出”We%20are%20happy."
分析:在空間復雜度盡可能低的情況下,不允許開辟一個新的數組來存放替換空格後的字符串。如果從前往後替換字符串,那麼保存在空格後面的字符串肯定會被覆蓋。假設字符串的長度為n。對每個空格字符,需要移動後面O(n)個字符,因此對含有O(n)個空格字符的字符串而言總的時間復雜度是O(n^2),明顯不可取。
思路:我們考慮從後往前進行替換,時間復雜度降為O(n)。
(1)首先遍歷一遍字符串,找出字符串的長度以及其中的空格數
(2)根據原字符串的長度和空格數求出最後新的字符串的長度
(3)設置兩個指針分別指向原字符串和新字符串的末尾位置
(4)如果原字符串的指針指向的內容不空,則將內容賦值給新指針指向的位置;否則從新指針開始向前賦值“02%”
(5)直到兩個指針相等時表明字符串中的所有空格已經替換完畢
C++代碼:
#include "stdafx.h"
#include <iostream>
using namespace std;
//將字符串str中的空格替換為"%20"
void ReplaceBlank(char *str)
{
int nOldLength = strlen(str);//計算字符串的長度
//遍歷字符串,求出其中空格的個數
int nCountOfBlank = 0;
char *p = str;
while (*p != '\0')
{
if (*p == ' ')
{
++nCountOfBlank;
}
++p;
}
int nNewLength = nOldLength + nCountOfBlank * 2;//新字符串的長度
int nOldIndex = nOldLength - 1;
int nNewIndex = nNewLength - 1;
while(nOldIndex != nNewIndex)
{
if (str[nOldIndex] != ' ')
{
str[nNewIndex--] = str[nOldIndex];
}
else
{
str[nNewIndex--] = '0';
str[nNewIndex--] = '2';
str[nNewIndex--] = '%';
}
--nOldIndex;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char str1[50] = "We are happy.";
ReplaceBlank(str1);
cout << str1 << endl;
char str2[50] = " We are happy. ";
ReplaceBlank(str2);
cout << str2 << endl;
char str3[50] = "";
ReplaceBlank(str3);
cout << str3 << endl;
char str4[50] = " ";
ReplaceBlank(str4);
cout << str4 << endl;
system("pause");
return 0;
}
#include "stdafx.h"
#include <iostream>
using namespace std;
//將字符串str中的空格替換為"%20"
void ReplaceBlank(char *str)
{
int nOldLength = strlen(str);//計算字符串的長度
//遍歷字符串,求出其中空格的個數
int nCountOfBlank = 0;
char *p = str;
while (*p != '\0')
{
if (*p == ' ')
{
++nCountOfBlank;
}
++p;
}
int nNewLength = nOldLength + nCountOfBlank * 2;//新字符串的長度
int nOldIndex = nOldLength - 1;
int nNewIndex = nNewLength - 1;
while(nOldIndex != nNewIndex)
{
if (str[nOldIndex] != ' ')
{
str[nNewIndex--] = str[nOldIndex];
}
else
{
str[nNewIndex--] = '0';
str[nNewIndex--] = '2';
str[nNewIndex--] = '%';
}
--nOldIndex;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char str1[50] = "We are happy.";
ReplaceBlank(str1);
cout << str1 << endl;
char str2[50] = " We are happy. ";
ReplaceBlank(str2);
cout << str2 << endl;
char str3[50] = "";
ReplaceBlank(str3);
cout << str3 << endl;
char str4[50] = " ";
ReplaceBlank(str4);
cout << str4 << endl;
system("pause");
return 0;
}
二、清除空格
請事先一個函數,把字符串中的每個空格清除。例如輸入“We are happy.",則輸出”Wearehappy."
分析:較為簡單,直接從頭到尾進行清除。
(1)設置兩個指針p1和p2初始狀態都指向字符串的首字符
(2)若p2指向的元素不空,則將p2指向的內容賦給p1,然後都指向下一個元素;否則為空格,則p2指向下一元素。
(3)直到p2指向字符串末尾“\0”時清除空格結束。
C++代碼:
#include "stdafx.h"
#include <iostream>
using namespace std;
//清除字符串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++;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char str1[50] = "We are happy.";
DeleteBlank(str1);
cout << str1 << endl;
char str2[50] = " We are happy. ";
DeleteBlank(str2);
cout << str2 << endl;
char str3[50] = "";
DeleteBlank(str3);
cout << str3 << endl;
char str4[50] = " ";
DeleteBlank(str4);
cout << str4 << endl;
system("pause");
return 0;
}
#include "stdafx.h"
#include <iostream>
using namespace std;
//清除字符串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++;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char str1[50] = "We are happy.";
DeleteBlank(str1);
cout << str1 << endl;
char str2[50] = " We are happy. ";
DeleteBlank(str2);
cout << str2 << endl;
char str3[50] = "";
DeleteBlank(str3);
cout << str3 << endl;
char str4[50] = " ";
DeleteBlank(str4);
cout << str4 << endl;
system("pause");
return 0;
}
三、清除多余空格
給定字符串,刪除開始和結尾處的空格,並將中間的多個連續的空格合並成一個。例如輸入“ We are happy. ”,則輸出“We are happy.”
分析:同樣是從前往後遍歷,但需要定義一個bool變量標記是否保存一個空格。初始化時被設置為fasle,這樣開始階段的空格都不會被保存,當碰到一個非空格字符時,保存該字符,然後將標記設置為true,表示會保存字符串中的第一個空格。經過上述幾步操作,可以保證字符串結尾要麼是空字符,要麼是非空格字符。如果是空格字符,則將其設置為"\0",如果不為空格字符,則在其後面加上"\0"。
C++代碼:
#include "stdafx.h"
#include <iostream>
using namespace std;
//清除字符串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);
}
int _tmain(int argc, _TCHAR* argv[])
{
char str1[50] = "We are happy.";
DeleteRedundantBlank(str1);
cout << str1 << endl;
cout << strlen(str1) << endl;
char str2[50] = " We are happy. ";
DeleteRedundantBlank(str2);
cout << str2 << endl;
cout << strlen(str2) << endl;
char str3[50] = "";
DeleteRedundantBlank(str3);
cout << str3 << endl;
char str4[50] = " ";
DeleteRedundantBlank(str4);
cout << str4 << endl;
system("pause");
return 0;
}
#include "stdafx.h"
#include <iostream>
using namespace std;
//清除字符串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);
}
int _tmain(int argc, _TCHAR* argv[])
{
char str1[50] = "We are happy.";
DeleteRedundantBlank(str1);
cout << str1 << endl;
cout << strlen(str1) << endl;
char str2[50] = " We are happy. ";
DeleteRedundantBlank(str2);
cout << str2 << endl;
cout << strlen(str2) << endl;
char str3[50] = "";
DeleteRedundantBlank(str3);
cout << str3 << endl;
char str4[50] = " ";
DeleteRedundantBlank(str4);
cout << str4 << endl;
system("pause");
return 0;
}