《資料結構》嚴蔚敏串的ADT實現 演算法4.1
這個沒有藉助C語言的庫函式,而是自己寫了一下字串操作函式.
測試用例有點水,將就著看吧。。。
附上c語言字串操作函式
// strcpy(p, p1) 複製字串
// strncpy(p, p1, n) 複製指定長度字串
// strcat(p, p1) 附加字串
// strncat(p, p1, n) 附加指定長度字串
// strlen§ 取字串長度
// strcmp(p, p1) 比較字串
// strcasecmp忽略大小寫比較字串
// strncmp(p, p1, n) 比較指定長度字串
// strchr(p, c) 在字串中查詢指定字元
// strrchr(p, c) 在字串中反向查詢
// strstr(p, p1) 查詢字串
// strpbrk(p, p1) 以目標字串的所有字元作為集合,在當前字串查詢該集合的任一元素
// strspn(p, p1) 以目標字串的所有字元作為集合,在當前字串查詢不屬於該集合的任一元素的偏移
// strcspn(p, p1) 以目標字串的所有字元作為集合,在當前字串查詢屬於該集合的任一元素的偏移
// strtod(p, ppend) 從字串 p 中轉換 double 型別數值,並將後續的字串指標儲存到 ppend 指向的 char
// strtol(p, ppend, base) 從字串 p 中轉換 long 型別整型數值,base 顯式設定轉換的整型進位制,設定為 0 以根據特定格式判斷所用進位制,0x, 0X 字首以解釋為十六進位制格式整型,0 字首以解釋為八進位制格式整型
// atoi§ 字串轉換到 int 整型
// atof§ 字串轉換到 double 符點數
// atol§ 字串轉換到 long 整型*
函式宣告
//string base operator //才意識到這是要自己動手造輪子,當函式名想不起來的時候還是很有幫助滴 #include<stdio.h> #include<stdlib.h> #include<string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 40 #define MAXSTRLEN 10 typedef int Status; typedef char SString[MAXSIZE+1]; //本程式碼中的字串操作函式 /*******************************宣告部分****************************************/ Status StrAssign(SString T,char *chars); //生成一個其值等於chars的串T 第一個元素為字串長度 int StrLength(SString S); //操作結果:返回S的元素個數,成為串的長度 Status StrCopy(SString S,SString T); //由串S複製得串T Status StrEmpty(SString S); //若S為空串返回TURE int StrCompare(SString S,SString T); //操作結果:若S>T,則返回值>0;若S = T,則返回值 =0;若S<T,則返回值<0 int StrLength(SString S); //返回S的元素個數,稱為串的長度 Status ClearString(SString S); //將S清為0串 Status StrConcat(SString T,SString S1,SString S2); //用T返回由S1,S2連結而成的新串 Status SubString(SString Sub, SString T,int pos,int len); //用Sub返回串T的第pos個字元起長度為len的子串 int Index(SString S,SString T,int pos); //若主串S中存在和串T值相同的子串,則返回它在主串中第pos個字元之後第一次出現的位置;否則函式值為0 Status Replace(SString S,SString T,SString V); //用V替換主串S中出現的所有與T相等的不重疊的子串 Status StrDelete(SString S,int pos,int len); //從主串S中刪除第pos個字元起長度為len的子串 Status StrInsert(SString S,int pos,SString T); //從主串S第pos個字元之前插入子串T Status DestroyString(SString S); //串S被摧毀 Status StrTraverse(SString S); //遍歷串S
函式定義
/*******************************函式部分****************************************/ Status StrAssign(SString T,char *chars) { int i,ct; for(i = 0;i <= MAXSIZE;i++) T[i] = '\0'; T[0] = strlen(chars); for(ct = 1;*chars != '\0';ct++,chars++) { T[ct] = *chars; } return OK; } //由串S複製得串T //這裡用了雙重指標 Status StrCopy(SString S,SString T) { int i; for(i = 0;i<=S[0];i++) T[i] = S[i]; return OK; } Status StrEmpty(SString S) { // if(S[0] == 0) // return OK; // else // return ERROR; //簡單寫法 return S[0] == 0; } int StrCompare(SString S,SString T) { int cnt = 1; while(cnt <= S[0] && cnt <= T[0]) { if(S[cnt] == T[cnt]) cnt ++; else return S[cnt] - T[cnt]; } //若都一直相等,那麼字串長的那個就大 return S[0] - T[0]; } int StrLength(SString S) { return S[0]; } //將S清為0串,這個好簡單的方法。。後面直接覆蓋值就行 Status ClearString(SString S) { S[0] = 0; return OK; } Status StrConcat(SString T,SString S1,SString S2) { int count,i; int uncut; //不用截斷 if(S1[0]+S2[0] <= MAXSTRLEN) { T[0] = S1[0] + S2[0]; for(count = 1;count <= S1[0];count++) T[count] = S1[count]; for(count = S1[0]+1,i = 1;count <= T[0];count++,i++) T[count] = S2[i]; uncut = TRUE; } //超出長度,需要截斷S2 else if(S1[0] < MAXSTRLEN) { T[0] = MAXSTRLEN; for(count = 1;count <= S1[0];count++) T[count] = S1[count]; for(count = S1[0]+1,i = 1;count <= T[0];count ++,i++) T[count] = S2[i]; uncut = FALSE; } //S1就需要截斷 else { T[0] = MAXSTRLEN; for(count = 1;count <= S1[0];count ++) T[count] = S1[count]; } return OK; } Status SubString(SString Sub,SString T,int pos,int len) { if( pos<1 || pos>T[0] || len < 0 || len > T[0]-pos+1 ) return ERROR; int ct,cnt; for(ct = 1,cnt = pos;cnt <= len+pos;ct++,cnt++) Sub[ct] = T[cnt]; Sub[0] = len+1; return OK; } int Index(SString S,SString T,int pos) { SString Sub; int i = pos; if(pos > 0) { int n = StrLength(S); int m = StrLength(T); while( i <= n-m+1) { SubString(Sub,S,i,m-1); if(StrCompare(Sub,T) == 0) return i; else i++; }//while }//if printf("no existence~\n"); return 0; } //串S,T,V存在,T是非空串 //用V替換主串S中所有出現的與T相等的不重疊的子串 Status Replace(SString S,SString T,SString V) { int i; i = Index(S,T,1); while(S[0]-T[0]+V[0] <= MAXSTRLEN && i) { StrDelete(S,i,T[0]); StrInsert(S,i,V); i += V[0]; i = Index(S,T,i); } if(i==0) return OK; else return ERROR; } Status StrInsert(SString S,int pos,SString T) { int i; if(pos<1 || pos>S[0]+1 || S[0]+T[0]>MAXSTRLEN) return ERROR; for(i = S[0];i>=pos;i--) S[i+T[0]] = S[i]; for(i = pos;i<pos+T[0]-1;i++) S[i] = T[i-pos+1]; S[0] += T[0]; return OK; } Status StrDelete(SString S,int pos,int len) { int i; if(pos<1 || pos+len-1>S[0] || len < 0) return ERROR; for(i = pos+len;i<=S[0];i++) S[i-len] = S[i]; S[0] -= len; return OK; } Status DestroyString(SString S) { free(S); return OK; } Status StrTraverse(SString S) { int i = 1; while(i <= S[0]) //字串下標是如何開始的啊,陣列當然從0開始啦,不過第一個位置存的是字串的長度 { printf("%c",S[i]); i++; } printf("\n"); return OK; }
//測試用例
int main(int argc, char const *argv[])
{
//測試用例
char *chars1 = "abcdefghijk";
char *chars2 = "defgh";
char *chars3 = "/**/";
SString S,T,V,W;
SString Q;
StrAssign(Q,chars3);
printf("\t**After StrAssign**\n");
StrAssign(S,chars1);
StrAssign(T,chars2);
printf("S: ");
StrTraverse(S);
printf("T: ");
StrTraverse(T);
printf("\t**After StrCopy**\n");
printf("copy T to V\n");
printf("V: ");
StrCopy(T,V);
StrTraverse(V);
printf("\t**After StrEmpty**\n");
int j = StrEmpty(W);
if(j == 1)
printf("W is empty!\n");
else
printf("W isn't empty!\n");
printf("\t**After StrCompare**\n");
int k = StrCompare(S,T);
if(k == 0)
printf("they have same length!\n");
if(k > 0)
printf("S is longer!\n");
if(k < 0)
printf("T is longer!\n");
printf("\t**After StrConcat**\n");
StrConcat(W,S,T);
printf("W: ");
StrTraverse(W);
printf("\t**After SubString**\n");
printf("from W situation 4,lengh is 5's SubString is: ");
SubString(V,W,4,5);
printf("V: ");
StrTraverse(V);
printf("\t**After Index**\n");
int ANSWER = Index(S,T,1);
printf("find substring in main String's situation = %d\n", ANSWER);
printf("\t**After Replace**\n");
Replace(S,T,Q);
printf("S: ");
StrTraverse(S);
printf("\t**After StrInsert**\n");
StrInsert(T,1,Q);
printf("T: ");
StrTraverse(T);
printf("\t**After StrDelete**\n");
StrDelete(T,1,3);
printf("T: ");
StrTraverse(T);
return 0;
}