順序表示的串——順序串——基本內容
字串、簡稱串,它也是一種重要的線性結構。計算機中處理的大部分資料都是字串資料,例如,學生學籍資訊系統的姓名、性別、家庭住址、院系名稱等資訊都屬於字串資料。串廣泛應用於各種專業的資訊管理、資訊檢索、問答系統、機器翻譯等系統處理中。
【定義】
串(string)是由零個或多個字元組成的有限序列,一般記作:
S="a1a2a3...an"。
其中,S是串名,用雙引號括起來的字元序列是串的值,ai(1≤i≤n)可以是字母、數字或其他字元,n是串的長度。當n=0時,S為空串(null string)。
串中任意一個連續的字元組成的子序列稱為該字元的子串。相應的包含子串的串稱為主串。通常將字元在串中的序號稱為該字元在串中的位置。子串在主串中的位置以子串的第一個字元在主串中的位置來表示。
例如:a、b、c、d是4個串:
a="a professor of Northwest University"
b="Northwest University"
c="Northwest"
d="professor"
它們的長度分別為35、20、9、10,b、c和d都是a的子串,c又是b的子串。b、c和d在a中位置分別是16,16,3,c在b中的位置是1。
兩個串是相等的,只有當兩個串長度相等,且串中各個對應位置的字元均相等,兩個串才相等。例如,上面的a,b,c,d兩輛都不相等。
值的注意的是,考慮到與C語言表示方法統一,本文的串都是用雙引號括起來的,但是,雙引號並不屬於串本身的內容,雙引號的作用僅僅是為了與整型浮點型資料區分開。
【分類】
串也有兩種儲存方式:順序儲存和鏈式儲存。最為常用的是串的順序儲存表示,操作起來更為方便。
【順序串】
採用順序儲存結構的串稱為順序串,又稱為定長順序串。一般採用字元型陣列存放順序串。在串的順序儲存結構中,確定串的長度有兩種方法:一種是在串的末尾加上一個結束標記,在C語言中,定義一個串時,系統會自動在串的末尾新增‘\0’作為結束標記。例如,定義一個字元陣列:
char str="Northwest University";
則串"Northwest University"在記憶體中的存放形式如圖所示。
其中陣列名str指向串的起始地址,“\0”表示串的結束。因此串"Northwest University"的長度為20,不包括結束標記“\0”。但是串長度還需要呼叫函式strlen或者統計字元個數得到。
另一種方法是增加一個變數length,用它來存放串的長度。例如,用length表示串"Northwest University"長度的方法如圖所示。
【儲存結構】
//儲存結構
typedef struct
{
char str[MAXSIZE];
int Length;
}SeqString;
【串的賦值】
//串的賦值
void StrAssign(SeqString *S, char cstr[])
{
int i=0;
for (i = 0; cstr[i] != '\0';i++)
{
S->str[i] = cstr[i];
}
S->Length = i;
}
【判斷串是否為空】
//判斷串是否為空
int StrEmpty(SeqString S)
{
if (S.Length==0)
{
return 1;
}
else
{
return 0;
}
}
【求串的長度】
//求串的長度
int StrLength(SeqString S)
{
return S.Length;
}
【串的複製】
//串的複製
void StrCopy(SeqString *T, SeqString S)
{
int i;
for (i = 0; i < S.Length;i++)
{
T->str[i] = S.str[i];
}
T->Length = S.Length;
}
【比較兩個串的大小】
//比較兩個串的大小
int StrCompare(SeqString S, SeqString T)
{
int i;
for (i = 0; i < S.Length&&T.Length;i++)
{
if (S.str[i]!=T.str[i])
{
return (S.str[i] - T.str[i]);
}
}
return (S.Length - T.Length);
}
【插入串】
在串的第pos位置插入串T。若插入成功,返回1;否則返回0.
串的插入操作具體實現分為3種情況:
第1種情況,在S中插入T後串長不超過能容納的最長字元,即S->Length+T.Length<=MaxLen
則先將串S中pos後的字元向後移動Len個位置,然後將串T插入S中即可;
第2種情況,若將T插入S後,串長超過能容納的最長字元但T能完全插入S中,即S->Length+T.Length>MaxLen
則將串S中pos後的字元往後移動Len個位置後,S中的部分字元被捨棄;
第3種情況,將T插入S中,有S->Length+T.Length>MaxLen且T不能完全被插入S中
則T中部分字元和S中第Len位置以後的字元均被捨棄。
/*在串的第pos位置插入串T。若插入成功,返回1;否則返回0.*/
/*串的插入操作具體實現分為3種情況:
第1種情況,在S中插入T後串長不超過能容納的最長字元,即S->Length+T.Length<=MaxLen
則先將串S中pos後的字元向後移動Len個位置,然後將串T插入S中即可;
第2種情況,若將T插入S後,串長超過能容納的最長字元但T能完全插入S中,即S->Length+T.Length>MaxLen
則將串S中pos後的字元往後移動Len個位置後,S中的部分字元被捨棄;
第3種情況,將T插入S中,有S->Length+T.Length>MaxLen且T不能完全被插入S中
則T中部分字元和S中第Len位置以後的字元均被捨棄。*/
int StrInsert(SeqString *S, int pos, SeqString T)
{
int i;
if (pos < 0||pos-1>S->Length)
{
cout << "插入位置不正確!";
return 0;
}
if (S->Length + T.Length <=MaxLen)
{
for (i = S->Length + T.Length - 1; i >= pos + T.Length - 1;i--)
{
S->str[i] = S->str[i - T.Length];
}
for (i = 0; i < T.Length;i++)
{
S->str[pos + i - 1] = T.str[i];
}
S->Length = S->Length + T.Length;
return 1;
}
else if (pos+T.Length<=MaxLen)
{
for (i = MaxLen - 1; i > T.Length + pos - 1;i--)
{
S->str[i] = S->str[i - T.Length];
}
for (i = 0; i < T.Length;i++)
{
S->str[i + pos - 1] = T.str[i];
}
S->Length = MaxLen;
return 0;
}
else
{
for (i = 0; i < MaxLen - pos;i++)
{
S->str[i + pos - 1] = T.str[i];
}
S->Length = MaxLen;
return 0;
}
}
【刪除串S中pos開始的len個字元】
/*刪除串S中pos開始的len個字元*/
int StrDelete(SeqString *S, int pos, int len)
{
int i;
if (pos<0||len<0||pos+len-1>S->Length)
{
cout << "刪除位置不合法,引數len不合法!";
return 0;
}
else
{
for (i = pos + len; i <= S->Length - 1;i++)
{
S->str[i - len] = S->str[i];
}
S->Length = S->Length - len;
return 1;
}
}
【連線串】
將串S連線在串T的末尾。串的連線操作可以分為兩種情況:
第1種,連線後串長T->Length+S.Length≤MaxLen,則直接將串S連線在串T的尾部;
第2種,連線後串長T->Length+S.Length≥MaxLen且串的長度<MaxLen,則串S會有字元丟失。
/*將串S連線在串T的末尾。串的連線操作可以分為兩種情況:
第1種,連線後串長T->Length+S.Length≤MaxLen,則直接將串S連線在串T的尾部;
第2種,連線後串長T->Length+S.Length≥MaxLen且串的長度<MaxLen,則串S會有字元丟失。*/
int StrConcat(SeqString *T, SeqString S)
{
int i, flag;
if (T->Length+S.Length<=MaxLen)
{
for (i = T->Length; i < T->Length + S.Length;i++)
{
T->str[i] = S.str[i - T->Length];
}
T->Length = T->Length + S.Length;
flag = 1;
}
else if(T->Length<MaxLen)
{
for (i = T->Length; i < MaxLen;i++)
{
T->str[i] = S.str[i - T->Length];
}
T->Length = MaxLen;
flag = 0;
}
return flag;
}
【清空串操作】
/*清空串操作*/
void StrClear(SeqString *S)
{
S->Length = 0;
}