1. 程式人生 > >資料結構上機實驗之串子系統

資料結構上機實驗之串子系統

C語言實現串子系統

這個串子系統是我借鑑網上一部分人的程式碼,然後自己添加註釋得到的,在原來的八個功能的基礎上添加了一個顯示字串長度的功能,所以一共九個功能。
功能分別為:
1、輸入字串
2、連線字串
3、取出子串
4、刪除子串
5、插入子串
6、查詢子串
7、比較串大小
8、顯示字串
9、顯示字串長度

還有一點想說的是,在第二個功能連線字串中,我使用了strcat()函式,以下是C語言函式中對其的介紹:
strcat:字串連線函式
函式原型:char *strcat (char *dest,char *src);
標頭檔案:#include<string.h>
是否是標準函式:是
函式功能:將兩個字串連接合併成一個字串,也就是把字串 src連線到字串 dest 後面,連線後的結果放在字串 dest 中
返回值:指向字串 dest 的指標
例程如下: 應用 strcat 連線字串。

 #include <string.h>  
 #include <stdio.h>  
 int main( ) 
  {    
  char dest[20]={“ ”};  
  char *hello = "hello ", *space = " ", *world = "world";   
  strcat(dest, hello);      
  strcat(dest, space);  
  strcat(dest, world);      
  printf("%s\n", destination);  
  getch();     
  return 0;
  } 

例程說明:
(1)首先,程式聲明瞭一個字元陣列和三個字串變數,將字元陣列 dest 初始化位空 串,其餘三個字串變數分別賦予初值。
(2)程式通過呼叫 strcat 函式實現字串的連線,首先將字串 hello 新增到字元陣列 dest 的末端,此時字元陣列 dest 的值有空串變為"hello",然後繼續呼叫兩次 strcat 函式,依 次將字串 space 和字串 world 陸續連線到字元陣列 dest 的末端,從而完成整個字串的 連線操作。
(3)最後將最終的結果輸出。
本例程最終的執行結果是:

hello world 

廢話不多說,直接上程式碼。

    #include<stdio.h>
    #include<string.h>
    #define MAXLEN 100	//串的最大長度	
    
    typedef struct
    {
    	char vec[MAXLEN];	//儲存串的一維陣列		
    	int len;			//串的當前長度 
    }str;
    
    //取出子串
    void SubStr(str *r,int i,int j) { 
    	int k; 
    	str a; 
    	str *r1=&a; 
    	
    	if (i+j-1 > r->len)	//判斷子要取出的串是否超出字串長度 
    		printf ("\n子串超界!\n");   
    	else  
    	{
    		for ( k=0; k<j; k++)	//迴圈取出子串存入r1 
    			r1->vec[k] = r->vec[i+k-1]; 
    		r1->len = j; 
    		r1->vec[r1->len] = '\0'; 
    	} 
    	printf("\n取出字元為:"); 
    	puts(r1->vec);	
    	
    }

//刪除子串
void DelStr(str *r,int i,int j) 
 {
	int k; 
	
	if(i+j-1 > r->len) //判斷需要刪除的子串是否超界 
		printf("\n所要刪除的子串超界!\n"); 
	else  
	{
		for ( k = i+j; k < r->len; k++,i++) //刪除子串,並將剩餘子串連線好 
			r->vec[i] = r->vec[k]; 
		r->len = r->len-j;
		r->vec[r->len] = '\0';
		printf("\n刪除成功!\n");
	}
	
}


//插入字串 
void InsStr(str *r,str *r1,int i)	
 {
	int k; 
	
	/*可以插入子串的條件,插入位置不超界且插入子串加原字串長度不得超過MAXLEN*/
	/*故插入位置超界或者 插入子串加原字串長度不得超過MAXLEN便不能插入*/ 
	if( i >= r->len || r->len+r1->len > MAXLEN) 
		printf("\n不能插入!\n"); 
	else 
	{
		for( k = r->len-1; k >= i; k--) //將字串位置i後的元素向後移動子串的長度個單位 
			r->vec[r1->len+k] = r->vec[k]; 
		for( k=0; k < r1->len; k++)	//再將子串插入字串對應位置中 
			r->vec[i+k] = r1->vec[k]; 
		r->len = r->len+r1->len; 
		r->vec[r->len] = '\0'; 
		printf("\n插入成功!\n");
	} 
	
} 


//查詢子串 
int IndexStr(str *s,str *t)  
{
	int i,j,k;     /* k記錄每一趟比較時子串的下標,均從0開始 */
	
	for( i=0; s->vec[i]; i++) 
		for( j=i,k=0; s->vec[j] == t->vec[k]; j++,k++) //如果不相等,退到外層迴圈 
			if(!t->vec[k+1]) 
				return i; 
	/*t->vec[k+1]為‘/0’表示子串比較完畢,返回匹配成功標誌*/			
	
	return -1; 
	/* 主串比較完畢即當s->vec[i]為‘/0’時結束外重迴圈,返回匹配不成功標誌 */
	
} 


//計算字串長度 
int LenStr(str *r)
 {	
	int i=0; 
	
	while(r->vec[i] != '\0') //累加計算字串長度 
		i++; 
		
	return i; 
	
} 


 //建立字串 
str *CreateStr(str *r)
 {
	gets(r->vec); 
	r->len = LenStr(r); 
	
	return r; 
	
} 


//比較兩字串大小 
int EqualStr(str *r1,str *r2) 
 {
	int i; 
	
	for( i=0; r1->vec[i] && r2->vec[i] && r1->vec[i] == r2->vec[i]; i++);
	/*此for迴圈是為了找到兩字串第一次元素不同的位置,並跳出迴圈*/ 
	
	return r1->vec[i]-r2->vec[i]; 
	/*然後 通過返回該位置兩字串元素的差,就能通過結果的正負來得出兩字串的大小比較*/ 
	
}


void main() 
 {
	str a,b,c,d; 
	str *r=&a,*r1=&b; 
	r->vec[0] = '\0'; 
	int i,j,choice; 
	
	while( 1 )  
	{    
		printf("\n                  串子系統                   \n");   
		printf("\n*********************************************");   
		printf("\n*            1------輸 入 字 串             *");   
		printf("\n*            2------連 接 字 串             *");   
		printf("\n*            3------取 出 子 串             *");   
		printf("\n*            4------刪 除 子 串             *");   
		printf("\n*            5------插 入 子 串             *");      
		printf("\n*            6------查 找 子 串             *");   
		printf("\n*            7------比較 串大小             *");   
		printf("\n*            8------顯 示 字 串             *");  
		printf("\n*            9------顯示字串長度            *"); 
		printf("\n*            0------返       回             *");   
		printf("\n*********************************************"); 
		
		printf("\n\n請選擇選單號(0--9): ");
		scanf("%d",&choice); 
		getchar(); 
		
		if(choice == 1) 
		{
			printf("\n請輸入一個字串:"); 
			gets(r->vec); 
			r->len=LenStr(r); 
			printf("\n輸入成功!\n");
		}
		else if(choice == 2) 
		{
			printf("\n請輸入所要連線的字串:"); 
			r1=CreateStr(&b); 
			strcat(r->vec,r1->vec);
			r->len=r->len+r1->len;
			printf("\n連線成功!\n"); 
		}
		else if(choice == 3) 
		{
			printf("\n請輸入從第幾個字元開始:"); 
			scanf("%d",&i);
			getchar(); 
			printf("\n請輸入取出的連續字元數:"); 
			scanf("%d",&j); 
			getchar(); 
			SubStr(r,i,j); 
		} 
		else if(choice == 4) 
		{
			printf("\n請輸入從第幾個字元開始:"); 
			scanf("%d",&i);
			getchar(); 
			printf("\n請輸入刪除的連續字元數:"); 
			scanf("%d",&j); 
			getchar(); 
			DelStr(r,i-1,j); 
			
		} 
		else if(choice == 5) 
		{  
			printf("\n請輸入在第幾個字元前插入: ");  
			scanf("%d",&i);  
			getchar();  
			printf("\n請輸入所要插入的子串: ");  
			r1=CreateStr(&b);   
			InsStr(r,r1,i-1); 
		} 
		else if(choice == 6) 
		{  
			printf("\n請輸入所要查詢的子串: ");  
			r1=CreateStr(&b); 
			i=IndexStr(r,r1);  
			if(i!=-1)   
				printf("\n該子串第一次出現的位置是第%d個。\n",i+1);  
			else    
				printf("\n該子串不在其中!\n"); 
		} 
		else if(choice == 7) 
		{   
			printf("\n請輸入第一個字串: ");  
			gets(c.vec);  
			printf("\n請輸入第二個字串串: ");  
			gets(d.vec);  
			if(EqualStr(&c,&d) > 0) 
				printf("\n第一個串大!\n"); 
			else if(EqualStr(&c,&d) < 0) 
				printf("\n第二個串大!\n"); 
			else 
				printf("\n兩個串一樣大!\n"); 
		} 
		else if(choice == 8) 
		{
			if(r->vec[0]=='\0') 
				printf("\n該字串值為空!\n"); 
			else
			{
				printf("\n該字串值為:");
				puts(r->vec); 
			} 
		} 
		else if(choice == 9)
			printf("字串長度為:%d",r->len);
		else if(choice == 0) 
			break; 
		else 
			printf("\n輸入有錯誤,請重新輸入\n"); 
			
	} 
	
}

程式執行截圖

選單執行介面

選單執行截圖
可以看到,選單總共有九個功能,輸入數字即可選擇對應的功能。

主要功能執行截圖

輸入字串
這裡一功能1舉例,輸入1,然後跳出提示語,此時輸入要輸入的字串,我這裡輸入的是:zxcvbn,其他功能暫不舉例,有興趣可以自己試驗。

總結

這裡的串子系統是使用的順序儲存實現,其儲存結構也與嚴蔚敏老師的資料結構第二版上提到的一致,在實現難度上,只要明確演算法,思路清晰,還是很容易實現的。