串:由零個(gè)或多個(gè)字符組成的有限序列,又名字符串坚冀。
實(shí)現(xiàn)代碼如下:
// 串存儲(chǔ)結(jié)構(gòu)
#include <stdio.h>
#include <string.h>
#define OK 1 // 執(zhí)行成功
#define ERROR 0 // 執(zhí)行失敗
#define TRUE 1 // 返回值為真
#define FALSE 0 // 返回值為假
#define MAXSIZE 20 // 存儲(chǔ)空間初始分配大小
typedef int Status; // 函數(shù)返回結(jié)果類型
// 串的存儲(chǔ)結(jié)構(gòu)济赎,0下標(biāo)位置用來存放字符串長度
typedef char String[MAXSIZE + 1];
/**
* 生成一個(gè)值等于字符串chars的字符串T
* @param T 新生成的字符串
* @param chars 原字符串
* @return 執(zhí)行狀態(tài)
*/
Status StrAssign(String T, char *chars) {
int i; // 用于遍歷元素
// 字符串chars的長度大于字符串T的分配空間,生成失敗
if (strlen(chars) > MAXSIZE) {
return ERROR;
} else {
// 計(jì)算字符串chars的長度,存到T的0下標(biāo)位置
T[0] = strlen(chars);
for (i = 1; i <= T[0]; ++i) {
// 將字符串chars的所有內(nèi)容存到字符串T中
T[i] = *(chars + i - 1); //(T從1下標(biāo)開始存司训,chars從0下標(biāo)開始取值构捡,所以要減1)
}
return OK;
}
}
/**
* 將串S的所有內(nèi)容復(fù)制到串T中
* @param T 新生成的串
* @param S 被復(fù)制的串
* @return 執(zhí)行狀態(tài)
*/
Status StrCopy(String T, String S) {
int i; // 用于遍歷元素
// 遍歷S的所有涌入
for (i = 0; i <= S[0]; ++i) {
T[i] = S[i];
}
return OK;
}
/**
* 判斷串是否為空
* @param S 串
* @return 是否為空串
*/
Status StrEmpty(String S) {
// 下標(biāo)為0的位置存儲(chǔ)串的長度,若等于0豁遭,串為空
if (S[0] == 0) {
return TRUE;
} else {
return FALSE;
}
}
/**
* 比較串S和T的大小
* 若S>T叭喜,返回值>0;若S=T蓖谢,返回值為0捂蕴;若S<T,返回值<0
* @param S 串
* @param T 串
* @return 串S是否比串T大
*/
int StrCompare(String S, String T) {
int i; // 用于遍歷元素
// 遍歷串的內(nèi)容
for (i = 0; i <= S[0] && i <= T[0]; i++) {
// 碰到對(duì)應(yīng)位置字符不相等
if (S[i] != T[i]) {
// 使用對(duì)應(yīng)位置
return S[i] - T[i];
}
}
// 使用兩個(gè)串的長度相減
return S[0] - T[0];
}
/**
* 返回串的元素個(gè)數(shù)
* @param S 串
* @return 串的元素個(gè)數(shù)
*/
int StrLength(String S) {
return S[0];
}
/**
* 將串的內(nèi)容清空
* @param S 串
* @return 執(zhí)行狀態(tài)
*/
Status ClearString(String S) {
S[0] = 0; // 令串的長度為0
return OK;
}
/**
* 連接S1和S2成新的串T
* 如果未截?cái)喾祷豑RUE闪幽,截?cái)鄤t返回FALSE
* @param T 連接成的新串
* @param S1 串
* @param S2 串
* @return 是否對(duì)連接成的字符串截?cái)? */
Status Concat(String T, String S1, String S2) {
int i; // 用于遍歷元素
// 串T的大小可以裝下串S1和串S2的內(nèi)容
if (S1[0] + S2[0] <= MAXSIZE) {
// 復(fù)制S1的所有內(nèi)容到T中
for (i = 1; i <= S1[0]; i++) {
T[i] = S1[i];
}
// 復(fù)制S2的所有內(nèi)容到T中
for (i = 1; i <= S2[0]; i++) {
T[S1[0] + i] = S2[i]; // S2的內(nèi)容在S1的內(nèi)容之后
}
// 串T的長度等于S1和S2的長度之和
T[0] = S1[0] + S2[0];
return TRUE; // 表示S2字符串未被截?cái)? }
// 串T的大小不能裝下串S1和串S2的內(nèi)容啥辨,將截?cái)郤2
else {
// 復(fù)制S1的所有內(nèi)容到T中
for (i = 1; i <= S1[0]; ++i) {
T[i] = S1[i];
}
// 當(dāng)未超過T的最大長度時(shí),復(fù)制S2的內(nèi)容到T中
for (i = 1; i <= MAXSIZE - S1[0]; i++) {
T[S1[0] + i] = S2[i]; // S2的內(nèi)容在S1的內(nèi)容之后
}
// T的長度等于限定的最大長度
T[0] = MAXSIZE;
return FALSE; // 表示字符串S2被截?cái)? }
}
/**
* 用串Sub返回串S第pos個(gè)字符起長度為len的字符
* @param Sub 截取的子串
* @param S 原串
* @param pos 開始截取位置
* @param len 截取長度
* @return 執(zhí)行狀態(tài)
*/
Status SubString(String Sub, String S, int pos, int len) {
int i; // 用于遍歷元素
// 截取的開始位置或長度不合理盯腌,截取失敗
if (pos < 1 || pos > S[0] || len < 0 || len > S[0] - pos + 1) {
return ERROR;
}
// 截取串S中從pos位置開始溉知,長度為len的內(nèi)容到串Sub中
for (i = 1; i <= len; ++i) {
Sub[i] = S[pos + i - 1];
}
// 將串Sub的長度設(shè)置為len
Sub[0] = len;
return OK;
}
/**
* 定位子串T在串S第pos個(gè)字符之后的位置,若不存在則返回0
* (此方法叫:樸素模式的匹配算法)
* @param S 原字符串
* @param T 子串
* @param pos 在S中開始定位的位置
* @return 子串T在串S第pos個(gè)字符之后的位置腕够,若不存在則返回0
*/
int Index(String S, String T, int pos) {
int i = pos; // i等于串S開始定位的下標(biāo)
int j = 1; // j用于記錄子串T中當(dāng)前下標(biāo)的位置
// i小于串S的長度级乍,并且j小于串T的長度
while (i <= S[0] && j <= T[0]) {
// 若對(duì)應(yīng)位置的字符相等,i和j都加1
if (S[i] == T[j]) {
i++;
j++;
} else { // 若對(duì)應(yīng)位置的字符不相等
i = i - j + 2; // i退回上次匹配首位的下一位
j = 1; // j退回子串T的首位
}
}
// 串T的所有元素都與S的某個(gè)子串相等
if (j > T[0]) {
return i - T[0]; // i位置減去串T的長度帚湘,得到子串的起始位置
} else { // 未定位到串T
return 0;
}
}
/**
* 在串S的第pos個(gè)位置插入串T的值
* 返回TRUE表示完全將T的內(nèi)容插入S中玫荣,F(xiàn)ALSE表示不能完全將T的內(nèi)容插入S中
* @param S 串S
* @param pos 下標(biāo)
* @param T 串T
* @return 執(zhí)行狀態(tài)
*/
Status StrInsert(String S, int pos, String T) {
int i; // 用于遍歷元素
// 插入位置不合理,插入錯(cuò)誤
if (pos < 1 || pos > S[0] + 1) {
return ERROR;
}
// 串T有足夠的位置完全插入串S中
if (S[0] + T[0] <= MAXSIZE) {
// 串S從i位置開始大诸,所有元素向后移動(dòng)串T的長度
for (i = S[0]; i >= pos; i--) {
S[i + T[0]] = S[i];
}
// 從第i個(gè)位置插入串T的值
for (i = pos; i < pos + T[0]; i++) {
S[i] = T[i - pos + 1];
}
// 設(shè)置S的長度為原來S的長度與T長度之和
S[0] = S[0] + T[0];
return TRUE; // 返回TRUE表示完全將T的內(nèi)容插入S中
} else { // 串T沒有有足夠的位置完全插入串S中捅厂,只能部分插入
// 將S的pos位置開始的元素向后移動(dòng)T個(gè)位置
for (i = MAXSIZE; i <= pos; i--) {
S[i] = S[i - T[0]];
}
// 從第i個(gè)位置插入串T的值
for (i = pos; i < pos + T[0]; i++) {
S[i] = T[i - pos + 1];
}
S[0] = MAXSIZE; // S的長度為最大初始值
return FALSE; // 返回FALSE表示不能完全將T的內(nèi)容插入S中
}
}
/**
* 從串S的第pos個(gè)位置開始,刪除len個(gè)長度的內(nèi)容
* @param S 串S
* @param pos 開始刪除的下標(biāo)
* @param len 刪除的長度
* @return 執(zhí)行狀態(tài)
*/
Status StrDelete(String S, int pos, int len) {
int i; // 用于遍歷元素
// 刪除位置不合理资柔,刪除失敗
if (pos < 1 || pos > S[0] - len + 1 || len < 0) {
return ERROR;
}
// 將被刪除位置的值用后面的值覆蓋
for (i = pos + len; i <= S[0]; i++) {
S[i - len] = S[i];
}
S[0] -= len; // S的長度減去len
return OK;
}
/**
* 串S中所有等于串T的內(nèi)容全都用串V進(jìn)行替換
* @param S 串S
* @param T 串T 被替換
* @param V 串V 替換的新內(nèi)容
* @return 執(zhí)行狀態(tài)
*/
Status Replace(String S, String T, String V) {
int i = 1; // 從串S的第一個(gè)字符起查找串T
// 串T是空串焙贷,替換失敗
if (StrEmpty(T)) {
return ERROR;
}
do {
i = Index(S, T, i); // 定位子串T在串S第pos個(gè)字符之后的位置
// 串T在串S中存在
if (i) {
StrDelete(S, i, StrLength(T)); // 在串S中刪除串T
StrInsert(S, i, V); // 在原串T的位置刪除串V
i += StrLength(V); // 在插入的串V的后面繼續(xù)查找串T
}
} while (i); // 當(dāng)串S中還有串T的存在
return OK;
}
/**
* 打印串的內(nèi)容
* @param T 串T
*/
void StrPrint(String T) {
int i; // 用于遍歷元素
// 打印字符串中所有元素的值
for (i = 1; i <= T[0]; i++) {
printf("%c", T[i]);
}
printf("\n");
}
int main() {
String t, s1, s2; // 串
Status status; // 執(zhí)行狀態(tài)
int index; // 起始坐標(biāo)
status = StrEmpty(t); // 判斷字符串t是否為空
printf("串t是否為空:%s\n", status == TRUE ? "是" : "否");
/*** 將字符串S賦值為abcd ***/
status = StrAssign(t, "ab");
printf("串t的值為:");
StrPrint(t); // 打印串t
printf("串t的長度為:%d\n", StrLength(t)); // 獲取串的長度
/*** 將字符串S賦值為abcd ***/
status = StrAssign(s1, "abcd"); // 將字符串S賦值為abcd
printf("將字符串S賦值為abcd后,串s1的值為:");
StrPrint(s1); // 打印串s1
printf("串s1的長度為:%d\n", StrLength(s1)); // 獲取串的長度
/*** 復(fù)制串s1的內(nèi)容到s2中 ***/
StrCopy(s2, s1); // 復(fù)制串s1的內(nèi)容到s2中
printf("復(fù)制串s1的內(nèi)容到s2后贿堰,串s2的值為:");
StrPrint(s2); // 打印串s2
printf("串s2的長度為:%d\n", StrLength(s1)); // 獲取串的長度
/*** 比較t和s1的大小 ***/
status = StrCompare(t, s1);
if (status > 0) {
printf("t大于s1\n");
} else if (status == 0) {
printf("t等于s1\n");
} else {
printf("t小于s2\n");
}
/*** 清空字符串s2中的內(nèi)容 ***/
status = ClearString(s2);
printf("s2是否為空串:%s\n", StrEmpty(s2) == TRUE ? "是" : "否");
/*** 將s1和s2連接后的值辙芍,賦值給串t ***/
status = StrAssign(s2, "efg"); // 重新賦值串s2等于efg
status = Concat(t, s1, s2); // 連接s1和s2的值,賦值給串t
printf("連接s1和s2的值到t后官边,串t的值為:");
StrPrint(t); // 打印串t
/*** 截取串t的部分內(nèi)容到串s2 ***/
status = SubString(s2, t, 2, 3); // 從串t的2下標(biāo)位置截取3個(gè)字符沸手,賦值給s2
printf("截取串t的部分內(nèi)容后,串s2的值為:");
StrPrint(s2); // 打印串
/*** 定位子串s2在串t中的起始位置 ***/
index = Index(t, s2, 0); // 定位子串s2在串t中的起始位置(從0下標(biāo)開始統(tǒng)計(jì))
printf("串s2在t的位置為:%d\n", index);
/*** 在串t下標(biāo)為4的位置插入串s1 ***/
status = StrInsert(t, 4, s1); // 在串t下標(biāo)為4的位置插入串s1
printf("下標(biāo)為4的位置插入s1后注簿,串t的值為:");
StrPrint(t); // 打印串
/*** 在串t下標(biāo)為4的位置刪除4個(gè)字符 ***/
status = StrDelete(t, 4, 4); // 在串t下標(biāo)為4的位置刪除4個(gè)字符
printf("下標(biāo)為4的位置刪除三個(gè)字符后契吉,串t的值為:");
StrPrint(t); // 打印串
/*** 替換串t中的abcd成123 ***/
status = StrAssign(s2, "123"); // 重新賦值串s2等于123
status = StrAssign(t, "abcdggggabcdggggabcd"); // 重新賦值給串t
status = Replace(t, s1, s2); // 在串t中,用s2的值替換調(diào)s1的值
printf("替換內(nèi)容后诡渴,串t的值為:");
StrPrint(t); // 打印串
}
運(yùn)行結(jié)果