劍指Offer-替換空格
題目:
請實現一個函數,將一個字符串中的空格替換成“%20”。例如,當字符串爲We Are Happy.則經過替換之後的字符串爲We%20Are%20Happy。
思路:
雙指針法(此處是記錄索引),首先遍歷數組獲取空格個數,每一個空格都要被替換成“%20”,則一個空格代表數組長度加2,首先計算數組需要增加的長度爲2*空格個數。
一個索引p1指向數組尾部,另外一個p2爲p1+2*空格個數。p1後向前開始遍歷,碰到空格,p2處修改爲“%20”;不是空格,p2處的值等於p1處的值。
這樣避免了從前往後遍歷帶來的碰到空格時需要移動後面所有元素的問題。當p1<0或者p2
#include<iostream>
using namespace std;
void replaceSpace(char* str,int length) {
int spacenum = 0;
int origin_length = 0;
for(int i=0;str[i]!='\0';i++) {
spacenum = (str[i]==' ')? spacenum+1:spacenum;
origin_length++;
}
int p1 = origin_length;
int p2 = origin_length + 2*spacenum;
while(p1>=0 && p2>p1) {
if(str[p1]==' ') {
str[p2--] = '0';
str[p2--] = '2';
str[p2--] = '%';
}
else
str[p2--] = str[p1];
p1--;
}
}
int main()
{
char a[20] = "We Are Happy";
replaceSpace(a, 12);
cout<<a<<endl;
return 0;
}
做這個題目過程中遇到幾個問題總結記錄一下。
1.char*和char[]
- 讀寫
char *a = "abc" //a是常量,可訪問但不可改變
char a[] = "abc" //a不是常量,可以改變
因此最好這樣聲明,則若改變其中元素會在編譯時期就報錯,而不是在運行時報錯:const char *a = “abc”;
- 賦值
char *a = "abc" //a在編譯時就確定(因爲常量)
char a[] = "abc" //a在運行時確定
- 存取效率
char *a = "abc" //常量存儲在靜態存儲區,慢
char a[] = "abc" //存於棧上,快
打印輸出
對於字符數組:直接cout<<數組名,不管是char*還是char[],得到的是數組所有元素,不是地址,因爲char*和char[]結尾都有’\0’,編譯器會根據’\0’判斷數組結束。
對於其他類型數組:打印得到的是首地址,因爲不存在結束符。附內存分配方式:
內存分配有三種:靜態存儲區、堆區和棧區。他們的功能不同,對他們使用方式也就不同。
靜態存儲區:內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。它主要存放靜態數據、全局數據和常量。
棧區:在執行函數時,函數(包括main函數)內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。(任何變量都處於站區,例如int a[] = {1, 2},變量a處於棧區。數組的內容也存在於棧區。)
堆區:亦稱動態內存分配。程序在運行的時候用malloc或new申請任意大小的內存,程序員自己負責在適當的時候用free或delete釋放內存。動態內存的生存期可以由我們決定,如果我們不釋放內存,程序將在最後才釋放掉動態內存。 但是,良好的編程習慣是:如果某動態內存不再使用,需要將其釋放掉,並立即將指針置位NULL,防止產生野指針。
2.string與char*、char[]之間的轉換
首先需要了解的是,string不一定以(‘\0’)結束,可以通過length獲取長度。
- string轉char*
轉換const char*,可以用c_str或者data函數。
string s1 = "abcdefg";
const char *k = s1.c_str(); //必須使用const修飾
const char *t = s1.data();
如果需要轉成char*,可以使用copy函數。
string s = "abcdefg";
char *data;
int len = s.length();
//data = (char*)malloc((len+1)*sizeof(char));
data = new char[len];
s.copy(data, len,0);
- char*或char[]轉string
可以直接賦值
string s;
char *a = "abc";
//char a[] = "abc";
s = a;
- string轉char[]
只能得到string.length,然後手動循環賦值。