上上週學習了串的部分知識,今天得空將其中的一些點整理下來。
資料結構中,字串要單獨用一種儲存結構來儲存,稱為串儲存結構。這裡的串指的就是字串。
嚴格意義上講,串儲存結構也是一種線性儲存結構,因為字串中的字元之間也具有"一對一"的邏輯關係。只不過,與之前所學的線性儲存結構不同,串結構只用於儲存字元型別的資料。
一些特殊的命名
空串:儲存 0 個字元的串,例如 s = 「」(雙引號緊挨著);
空格串:只包含空格字元的串,例如 s = " "(雙引號包含 5 個空格);
子串和主串:假設有兩個串 a 和 b,如果 a 中可以找到幾個連續字元組成的串與 b 完全相同,則稱 a 是 b 的主串,b 是 a 的子串。例如,若 a = 「shujujiegou」,b = 「shuju」,由於 a 中也包含 「shuju」,因此串 a 和串 b 是主串和子串的關係;
需要注意的是,空格串和空串不同,空格串中含有字元,只是都是空格而已。另外,只有串 b 整體出現在串 a 中,才能說 b 是 a 的子串,比如 「shujiejugou」 和 「shuju」 就不是主串和子串的關係。
另外,對於具有主串和子串關係的兩個串,通常會讓你用演算法找到子串在主串的位置。子串在主串中的位置,指的是子串首個字元在主串中的位置。
例如,串 a = 「shujujiegou」,串 b = 「jiegou」,通過觀察,可以判斷 a 和 b 是主串和子串的關係,同時子串 b 位於主串 a 中第 6 的位置,因為在串 a 中,串 b 首字元 『j』 的位置是 6。
串儲存結構的具體實現
儲存乙個字串,資料結構包含以下 3 種具體儲存結構:
(1)定長順序儲存:實際上就是用普通陣列(又稱靜態陣列)儲存。
(2)堆分配儲存:用動態陣列儲存字串;
(3)塊鏈儲存:用鍊錶儲存字串;
首先介紹一下串的定長順序儲存:
串的定長順序儲存結構,可以簡單地理解為採用 「固定長度的順序儲存結構」 來儲存字串,因此限定了其底層實現只能使用靜態陣列。
使用定長順序儲存結構儲存字串時,需結合目標字串的長度,預先申請足夠大的記憶體空間。
#include
intmain()
上面這段 c 語言**給大家完美地展示了使用定長順序儲存結構儲存字串。
串的堆分配儲存結構,其具體實現方式是採用動態陣列儲存字串。
通常,程式語言會將程式占有的記憶體空間分成多個不同的區域,程式包含的資料會被分門別類並儲存到對應的區域。拿 c 語言來說,程式會將記憶體分為 4 個區域,分別為堆區、棧區、資料區和**區,其中的堆區是本節所關注的。
與其他區域不同,堆區的記憶體空間需要程式設計師手動使用 malloc 函式申請,並且在不用後要手動通過 free 函式將其釋放。
c 語言中使用 malloc 函式最多的場景是給陣列分配空間,這類陣列稱為動態陣列。例如:
char
* a =
(char*)
malloc(5
*sizeof
(char))
;
此行**建立了乙個動態陣列 a,通過使用 malloc 申請了 5 個 char 型別大小的堆儲存空間。
a =
(char*)
realloc
(a,10
*sizeof
(char))
;
通過使用這行**,之前具有 5 個 char 型儲存空間的動態陣列,其容量擴大為可儲存 10 個 char 型資料。
#include
#include
#include
intmain()
//合併兩個串到 a1 中
for(
int i = lengtha1; i < lengtha1 + lengtha2; i++
)//串的末尾要新增 \0,避免出錯
a1[lengtha1 + lengtha2]
='\0'
;printf
("%s"
, a1)
;//用完動態陣列要立即釋放
free
(a1)
;free
(a2)
;return0;
}
程式執行結果:
data.biancheng.net
注意,程式中給 a1 和 a2 賦值時,使用了 strcpy 複製函式。這裡不能直接用 a1 =「data.biancheng」,程式編譯會出錯,報錯資訊為 「沒有 malloc 的空間不能 free」。因為 strcpy 函式是將字串複製到申請的儲存空間中,而直接賦值是字串儲存在別的記憶體空間(本身是乙個常量,放在資料區)中,更改了指標 a1 和 a2 的指向,也就是說,之前動態申請的儲存空間雖然申請了,結果還沒用呢就丟了。
串的塊鏈儲存,指的是使用鍊錶結構儲存字串。
我們知道,單鏈表中的 「單」 強調的僅僅是鍊錶各個節點只能有乙個指標,並沒有限制資料域中儲存資料的具體個數。因此在設計鍊錶節點的結構時,可以令各節點儲存多個資料。
鍊錶各節點儲存資料個數的多少可參考以下幾個因素:
1.串的長度和儲存空間的大小:若串包含資料量很大,且鍊錶申請的儲存空間有限,此時應盡可能的讓各節點儲存更多的資料,提高空間的利用率(每多乙個節點,就要多申請乙個指標域的空間);反之,如果串不是特別長,或者儲存空間足夠,就需要再結合其他因素綜合考慮;
2.程式實現的功能:如果實際場景中需要對儲存的串做大量的插入或刪除操作,則應盡可能減少各節點儲存資料的數量;反之,就需要再結合其他因素。
#include
#include
#include
#define linknum 3
//全域性設定鍊錶中節點儲存資料的個數
typedef
struct link link;
// nk為節點名,每個節點都是乙個 link 結構體
link *
initlink
(link * head,
char
* str)
;void
displaylink
(link * head)
;int
main()
//初始化鍊錶,其中head為頭指標,str為儲存的字串
link *
initlink
(link * head,
char
* str)
//建立並初始化首元節點
head =
(link*
)malloc
(sizeof
(link));
head->next =
null
; link *temp = head;
//初始化鍊錶
for(
int i =
0; i)else
temp->a[j]
='#';}
if(i*linknum + j < length)
}return head;
}//輸出鍊錶
void
displaylink
(link * head)
temp = temp->next;
}}
程式輸出結果為:
data.biancheng.net
串的基礎就先整理到這裡啦,下次將更新bf演算法(串模式匹配演算法)。 資料結構與演算法(串)
引言 在上次佇列學習後,現在我們再學習串。主要包含kmp演算法,現在就開始資料結構與演算法的 串的學習。定義 串是由零個或者多個字元組成的有限序列,又叫字串。串的大部分操作我們曾經都實現過,這裡重點介紹kmp演算法。樸素模式匹配演算法是我們最容易思考到的一種普通演算法,其時間複雜度可以認為是o n ...
資料結構與演算法基礎
電腦科學的研究物件是問題 解決問題的過程,以及通過該過程得到解決方案。演算法是具有有限步驟的過程,依照這個過程能解決問題。因此,演算法就是解決方案。電腦科學是研究問題及其解決方案,以及研究目前無解的問題的科學。可以簡答的認為電腦科學就是研究演算法的科學。抽象資料元素 沒有實際含義的資料元素,例如 a...
資料結構與演算法基礎
一 資料結構概述 資料結構的主要任務是通過分析資料物件的結構特徵,包括邏輯結構及資料物件之間的關係,然後把邏輯結構表示成計算機課實現的物理結構,從而便於計算機處理。概念術語 二 資料的邏輯結構與物理結構 邏輯結構 logical structure 是指在資料物件中資料元素之間的相互關係。資料元素之...