1. 程式人生 > >《資料結構》嚴蔚敏串的ADT實現 演算法4.1

《資料結構》嚴蔚敏串的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;
}