首頁  >  文章  >  串是一種資料物件和運算都特殊的線性表嗎

串是一種資料物件和運算都特殊的線性表嗎

青灯夜游
青灯夜游原創
2021-02-03 11:14:5712387瀏覽

是的,字串是一種資料物件和運算都特殊的線性表結構。資料結構中提到的字串,即字串;字串中的字元之間具有「一對一」的邏輯關係,所以嚴格意義上講,串存儲結構是一種線性儲存結構。

串是一種資料物件和運算都特殊的線性表嗎

本教學操作環境:windows7系統、Dell G3電腦。

資料結構中提到的字串,即字串,由 n 個字元組成的一個整體( n >= 0 )。這 n 個字元可以由字母、數字或其他字元組成。

資料結構中,字串要單獨用一種儲存結構來存儲,稱為串存結構。

嚴格意義上講,字串儲存結構也是一種線性儲存結構,因為字串中的字元之間也具有"一對一"的邏輯關係。只不過,與先前所學的線性儲存結構不同,而串結構只用於儲存字元類型的資料。

特殊的字串

  • #空白字串:含有零個字元的字串。例如:S = “”(雙引號中沒有任何東西),一般直接用 Ø 表示。

  • 空格字串:只包含空格的字串。注意和空串區分開,空格串中是有內容的,只不過包含的是空格,且空格串中可以包含多個空格。例如,a = ” 」(包含3個空格)。

  • 子字串與主字串:字串中任一連續字元組成的字串叫做該字串的子字串,包含子字串的字串稱為主字串。

例如:a = ”BEI”,b = ”BEIJING”,c = ”BJINGEI” 。對於字串a 和b 來說,由於b 中含有連續的字串a ,

所以可以稱a 是b 的子字串,b 是a 的主字串;而對於c 和a ,雖然c中也含有a 的全部字符,但不是連續的“BEI” ,所以串c 和a 沒有任何關係。

子字串在主字串中的位置:對於字串a = ”BEI” 來說,首字元'B' 在字串b 的位置為1 ,所以子字串a 在主字串b = “BEIJING” 中的位置是1。

子字串在主字串中的位置和字元在陣列中的存放位置不同,子字串在主字串的位置從 1 開始數。

兩個字串相等的標準:如果兩個字串的字串值完全相同,那麼這兩個字串相等。

字串的三種儲存架構

#儲存字串的結構有三種:

#1 定長順序儲存;

2 堆分配儲存;

3 區塊鏈儲存。

定長順序儲存

採用固定長度的陣列(即靜態陣列)儲存字串。

例如:char a[7] = "abcdfg";

此方式儲存字串時,需要預估字串的長度提前申請足夠的儲存空間。目標串若超過了陣列申請的長度,超出部分會被自動捨棄(稱為「截斷」)。

例如:char a[3] = "abcdfg";//實際上數組中只儲存了 “abc” ,後邊的被截斷。堆分配儲存

採用動態數組儲存字串

在C語言中,存在著一個被稱為「堆」的自由儲存區,用malloc 函數和free 函數管理,malloc 函數負責申請空間,free 函數負責釋放空間。

例如:

char * a = (char*)malloc(5*sizeof(char));//创建 a 数组,动态申请5个 char 类型数据的存储空间

使用堆疊分配儲存的優點在於:當發現申請的空間不夠用時,可以透過 realloc() 函數重新申請更大的儲存空間。

例如:a = (char*)realloc(a, 10*sizeof(char));//前一个参数指申请空间的对象;第二个参数,重新申请空间的大小

使用 malloc 函數申請的儲存空間,不會自動釋放,需要程式設計師呼叫 free() 函數手動釋放。如果不手動釋放,當程式執行徹底結束,由作業系統進行回收。

例如:free(a);//释放动态数组a申请的空间

舉一個完整的例子,連接字串「abc」 和「defg」 變成「abcdefg」;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char * a1=NULL;
    char * a2=NULL;
    
    a1=(char*)malloc(3*sizeof(char));
    strcpy(a1, "abc");//将字符串“abc”复制给a1
    
    a2=(char*)malloc(3*sizeof(char));
    strcpy(a2, "defg");
    
    int lengthA1=strlen(a1);
    int lengthA2=strlen(a2);
    if (lengthA1<lengthA1+lengthA2) {
        a1=(char*)realloc(a1, (lengthA1+lengthA2)*sizeof(char));
    }
    int i;
    for (i=lengthA1; i<lengthA1+lengthA2; i++) {
        a1[i]=a2[i-lengthA1];
    }
    printf("%s",a1);
    
    free(a1);
    free(a2);
    return 0;
}

串是一種資料物件和運算都特殊的線性表嗎

註:在程式中,我們給a1 和a2 賦值的時候,使用了strcpy 複製函數。這裡不能直接用:a1 = ”abc」這種方式,

如果你這樣做,程式編譯會出錯,告訴你,沒有 malloc 的空間不能 free 。

原因是: strcpy 函數是將字串複製到申請的儲存空間中,而直接賦值是字串儲存在別的記憶體空間(本身就是一個常數,放在常數區)中,

更改了指針a1 和a2 的指向,也就是說,之前動態申請的儲存空間雖然申請了,結果還沒用呢就丟了。

塊鏈存儲

塊鏈存儲,其實就是藉用鍊錶的存儲結構來存儲串。一般情況下使用單鍊錶就夠了,而且不需要增設頭結點。

在建立鍊錶時,每個結點可以存放一個字符,也可以存放多個字符。

串是一種資料物件和運算都特殊的線性表嗎

链表中最后一个结点的数据域不一定全被串值占满,通常会补上 “#” 或者其他特殊的字符和字符串中的字符区分开。

每个结点设置字符数量的多少和存储的串的长度、可以占用的存储空间以及程序实现的功能相关。

如果串包含数据量很大,但是可用的存储空间有限,那么就需要提高空间利用率,相应地减少结点数量(因为多一个节点,就多申请一个指针域的空间)。

而如果程序中需要大量地插入或者删除数据,如果每个节点包含的字符过多,操作字符就会变得很麻烦,为实现功能增加了障碍。

总结

在平时编写程序,经常会用到例如:char *a = ”abcd”;这种方式表示字符串,和上面三种存储方式最主要的区别是:这种方式用于表示常量字符串,只能使用,不能对字符串内容做修改(否则程序运行出错);而以上三种方式都可以对字符串进行删改的操作。

例如:

#include <stdio.h>
int main() {
    char* a="abcd";
    a[1]=&#39;b&#39;;
    return 0;
}

程序编译可以通过,运行失败,改成下面堆分配存储的方式就对了:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
    char * a=(char*)malloc(4*sizeof(char));
    strcpy(a, "abcd");
    a[1]=&#39;e&#39;;
    printf("%s",a);
    return 0;
}

串是一種資料物件和運算都特殊的線性表嗎

三种存储表示方式中,最常用的是堆分配存储,因为它在定长存储的基础上通过使用动态数组,避免了在操作串时可能因为申请存储空间的不足而丢失字符数据;和块链存储方式相比,结构相对简单,更容易操作。

更多计算机编程相关知识,请访问:编程视频!!

以上是串是一種資料物件和運算都特殊的線性表嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn