1. 程式人生 > >順序表示的串——順序串——基本內容

順序表示的串——順序串——基本內容

字串、簡稱串,它也是一種重要的線性結構。計算機中處理的大部分資料都是字串資料,例如,學生學籍資訊系統的姓名、性別、家庭住址、院系名稱等資訊都屬於字串資料。串廣泛應用於各種專業的資訊管理、資訊檢索、問答系統、機器翻譯等系統處理中。

【定義】

串(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;
}