一、 串的基本概念
串(或字符串),是由零個或多個字符組成的有窮序列。
含零個字符的串稱爲空串,用Ф表示。串中所含字符的個數稱爲該串的長度(或串長)。
通常將一個串表示成“a1a2…an”的形式。其中最外邊的雙引號本身不是串的內容,它們是串的標誌,以便將串與標識符(如變量名等)加以區別。每個ai(1≤i≤n)代表一個字符。
當且僅當兩個串的長度相等並且各個對應位置上的字符都相同時,這兩個串纔是相等的。
一個串中任意個連續字符組成的子序列(含空串)稱爲該串的子串。例如,“a”、“ab”、“abc”和“abcd”等都是“abcde”的子串(真子串是指不包含自身的所有子串)。
二、串的順序存儲及其基本操作實現
在順序串中,串中的字符被依次存放在一組連續的存儲單元裏。一般來說,一個字節(8位)可以表示一個字符(即該字符的ASCII碼)。
因此,一個內存單元可以存儲多個字符。例如,一個32位的內存單元可以存儲4個字符(即4個字符的ASCII碼)。
串的順序存儲有兩種方法:一種是每個單元只存一個字符,這稱爲非緊縮格式(其存儲密度小);另一種是每個單元存放多個字符,這稱爲緊縮格式(其存儲密度大)。
對於非緊縮格式的順序串,其類型定義如下:
#define MaxSize 100
typedef struct
{ char data[MaxSize];
int length;
} SqString;
順序串中實現串的基本運算如下:
(1)StrAssign(s,cstr)
將一個字符串常量賦給串s,即生成一個其值等於cstr的串s。
void StrAssign(SqString &s,char cstr[])//s爲引用型參數
{ int i;
for (i=0;cstr[i]!='\0';i++)
s.data[i]=cstr[i];
s.length=i;
}
(2)StrCopy(s,t)
將串t複製給串s。
void StrCopy(SqString &s,SqString t)//s爲引用型參數
{ int i;
for (i=0;i<t.length;i++)
s.data[i]=t.data[i];
s.length=t.length;
}
(3)StrEqual(s,t)
判串相等:若兩個串s與t相等返回真(1);否則返回假(0)。
bool StrEqual(SqString s,SqString t)
{ bool same=true;
int i;
if (s.length!=t.length) //長度不相等時返回0
same=false;
else
for (i=0;i<s.length;i++)
if (s.data[i]!=t.data[i])
{ same=false;
break;
}
return same;
}
(4)StrLength(s)
求串長:返回串s中字符個數。
int StrLength(SqString s)
{
return s.length;
}
(5)Concat(s,t)
串連接:返回由兩個串s和t連接在一起形成的新串。
SqString Concat(SqString s,SqString t)
{ SqString str;
int i;
str.length=s.length+t.length;
for (i=0;i<s.length;i++) //s.data[0..s.length-1]str
str.data[i]=s.data[i];
for (i=0;i<t.length;i++) //t.data[0..t.length-1]str
str.data[s.length+i]=t.data[i];
return str;
}
(6)SubStr(s,i,j)
求子串:返回串s中從第i(1≤i≤StrLength(s))個字符開始的、由連續j個字符組成的子串。參數不正確時返回一個空串。
SqString SubStr(SqString s,int i,int j)
{ SqString str;
int k;
str.length=0;
if (i<=0 || i>s.length || j<0 || i+j-1>s.length)
return str; //參數不正確時返回空串
for (k=i-1;k<i+j-1;k++) //s.data[i..i+j]str
str.data[k-i+1]=s.data[k];
str.length=j;
return str;
}
(7)InsStr(s1,i,s2)
將串s2插入到串s1的第i(1≤i≤StrLength(s)+1)個字符中,即將s2的第一個字符作爲s1的第i個字符,並返回產生的新串。參數不正確時返回一個空串。
SqString InsStr(SqString s1,int i,SqString s2)
{ int j; SqString str;
str.length=0;
if (i<=0 || i>s1.length+1) //參數不正確時返回空串
return str;
for (j=0;j<i-1;j++) //將s1.data[0..i-2]str
str.data[j]=s1.data[j];
for (j=0;j<s2.length;j++) //s2.data[0..s2.length-1]str
str.data[i+j-1]=s2.data[j];
for (j=i-1;j<s1.length;j++) //s1.data[i-1..s1.length-1]str
str.data[s2.length+j]=s1.data[j];
str.length=s1.length+s2.length;
return str;
}
(8)DelStr(s,i,j)
從串s中刪去第i(1≤i≤StrLength(s))個字符開始的長度爲j的子串,並返回產生的新串。參數不正確時返回一個空串。
SqString DelStr(SqString s,int i,int j)
{ int k; SqString str;
str.length=0;
if (i<=0 || i>s.length || i+j>s.length+1) return str; //參數不正確時返回空串
for (k=0;k<i-1;k++) //s.data[0..i-2]str
str.data[k]=s.data[k];
for (k=i+j-1;k<s.length;k++) //s.data[i+j-1..s.length-1]str
str.data[k-j]=s.data[k];
str.length=s.length-j;
return str;
}
(9)RepStr(s,i,j,t)
在串s中,將第i(1≤i≤StrLength(s))個字符開始的j個字符構成的子串用串t替換,並返回產生的新串。參數不正確時返回一個空串。
SqString RepStr(SqString s,int i,int j,SqString t)
{ int k; SqString str; str.length=0;
if (i<=0 || i>s.length || i+j-1>s.length)
return str; //參數不正確時返回空串
for (k=0;k<i-1;k++) //s.data[0..i-2]str
str.data[k]=s.data[k];
for (k=0;k<t.length;k++) //t.data[0..t.length-1]str
str.data[i+k-1]=t.data[k];
for (k=i+j-1;k<s.length;k++) //s.data[i+j-1..s.length-1]str
str.data[t.length+k-j]=s.data[k];
str.length=s.length-j+t.length;
return str;
}
(10)DispStr(s)
輸出串s的所有元素值。
void DispStr(SqString s)
{ int i;
if (s.length>0)
{ for (i=0;i<s.length;i++)
printf("%c",s.data[i]);
printf("\n");
}
}