數據結構——串的相關算法實現


數據結構——串的相關算法實現

順序串的插入函數實現

在進行順序串的插入時,插入pos將串分為兩個部分(假設為A、B,長度為LA、LB)及待插入部分(假設為C,長度為LC),則串由插入前的AB變為ACB,由於是順序串,插入會引起元素的移動。可能會出現以下的三種情況:

  • ①插入后串長度(LA+LC+LB)<=MAXLEN,則將B后移LC個元素位置,再將C插入;
  • ②插入后串長度 >=MAXLEN 且 pos+LC <=MAXLEN,則 B 后移時會有部分字符被舍棄;
  • ③插入后串長度>MAXLEN 且 pos+LC > MAXLEN,則 B 的全部字符被舍棄(不需要后移),並且C在插入時也有部分字符被舍棄。

代碼實現

#include<stdio.h>
 
#define MAX_SIZE 128
 
typedef struct
{
    char ch[MAX_SIZE];
    int last;
}string;
 
void init_str(string * s, int max)
{
    int i;
 
    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而誰的 ASCII 碼對應的是 整型的0呢?是字符'\0'
    s->last = 0;
}
 
void create_str(string * s, char * a, int n)
{
    int i=0; 
    for(;i < n; i++)
        s->ch[i] = a[i];
 
    s->ch[i+1] = '\0';
    s->last = n;
    printf("你輸入的字符串為:\n");
    printf("%s\n",s->ch);
}
 
void insert_str(string * s,char * substr, int len, int pos)
{
    int i;
 
    if(pos < 0 || pos >= MAX_SIZE)
    {
        printf("輸入的位置不合理!\n");
        return;
    }
 
    if (s->last + len >= MAX_SIZE) {
        printf("Can't insert, new string too long!\n");
        return;
    }
 
    if (pos >= s->last) {    /* 若插入的位置在last之后*/
        for (i = 0; i < len; i++)
            s->ch[s->last+i] = substr[i];//把新插入的串從s串的組后開始插入 
        s->ch[s->last+i] = 0;//插入新串之后,字符串的最末尾'\0' ,0 是'\0' 的 ASCII 
        puts(s->ch);
        s->last += len;
    } else {    /* 若插入的位置在ch內*/
        for (i = 0; i < len; i++)
            s->ch[pos+len+i] = s->ch[pos+i];//在沒有插入新的串之前把s串分2部分,然后把后面部分整體向后移動len個長度
											//即,給即將要插入的串“騰空 ” 
 
        for (i = 0; i < len; i++)
            s->ch[pos+i] = substr[i]; //把新的串插入到剛剛騰出來的地方 
        s->ch[s->last+len] = 0; //插入后的“串”已經確定,改變了最后'/0'位置 
        s->last += len; //串的最大長度也重新確定 即,s->last = s->last+len 
    }
}
int main()
{
    string s;
    int pos, i;
    char a[80],b[80];
 
    init_str(&s, MAX_SIZE);
    printf("請輸入字符串:\n");
    scanf("%s",a);
 
    /* 遍歷整個字符串,並把a[]中的字符存在s中,長度為i ,然后輸出*/
    for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者這個准確些 
        ;
    create_str(&s, a, i);// 
    printf("請輸入你要插入的字符串:\n");
    scanf("%s", b);
 
    for(i = 0; b[i]; i++)
        ;
    printf("請輸入你要插入的位置:\n");
    scanf("%d",&pos);
    insert_str(&s, b, i, pos);//找到原來的串“s”,把b[]中的字符存進去,新插入的字符串的長度為i,插入的
	                           // 位置為pos
								 
    printf("新的字符串為:\n");
    printf("%s\n",s.ch);//輸出插入后 所組成的 新串 
    return 0;
}

串的刪除函數實現

指定要刪除的位置,和從此位置要刪除的字符的長度,實現刪除字符串的刪除操作。

代碼實現

#include<stdio.h>
 
#define MAX_SIZE 128
 
typedef struct
{
    char ch[MAX_SIZE];
    int last;
}string;
 
void init_str(string * s, int max)
{
    int i;
 
    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而誰的 ASCII 碼對應的是 整型的0呢?是字符'\0'
    s->last = 0;
}
 
void create_str(string * s, char * a, int n)
{
    int i=0; 
    for(;i < n; i++)
        s->ch[i] = a[i];
 
    s->ch[i+1] = '\0';
    s->last = n;
    printf("你輸入的字符串為:\n");
    printf("%s\n",s->ch);
}
 

//順序串的刪除函數

void StrDelete(string * s,int pos,int len)
{
	int i;
	if(pos<0||pos>(s->last-len))
		{
			printf("刪除參數不合法!");
			return; 
		}
	for(i=pos+len;i<s->last;i++)
	{
		s->ch[i-len] = s->ch[i];
	}
	s->ch[s->last-len] = 0;
	s->last = s->last - len;
}


 
int main()
{
    string s;
    int pos, i,n;
    char a[80];
 
    init_str(&s, MAX_SIZE);
    printf("請輸入字符串:\n");
    scanf("%s",a);
 
   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者這個准確些 
        ;
    create_str(&s, a, i);// 
    
	                           
	printf("請輸入要刪除的位置 及字符串長度:");
	scanf("%d %d",&pos,&n);
	StrDelete(&s,pos,n);
								 
    printf("新的字符串為:\n");
    printf("%s\n",s.ch);//輸出插入后 所組成的 新串 
    return 0;
}

串的比較函數實現

串的比較,即對兩個字符串進行比較(ascii)在本例中,若串s和相等,則返回0,若s>t則返回正數,反之則返回負數。

代碼實現

#include<stdio.h>
 
#define MAX_SIZE 128
 
typedef struct
{
    char ch[MAX_SIZE];
    int last;
}string;
 
void init_str(string * s, int max)
{
    int i;
 
    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而誰的 ASCII 碼對應的是 整型的0呢?是字符'\0'
    s->last = 0;
}
 
void create_str(string * s, char * a, int n)
{
    int i=0; 
    for(;i < n; i++)
        s->ch[i] = a[i];
 
    s->ch[i+1] = '\0';
    s->last = n;
    printf("你輸入的字符串為:\n");
    printf("%s\n",s->ch);
}
 


//串比較函數

int StrCompare(string s,string t)
{
	/*若串s和t相等則返回0,若s>t則返回正數;若s<t,則返回負數*/
	int i;
	int equle = 0;
	for(i=0;i<s.last&&i<t.last;i++)
	{
		if(s.ch[i]!=t.ch[i])
			return(s.ch[i]-t.ch[i]);//都是ascii碼 
		
	}
	return equle;
	
} 
 
int main()
{
    string s,t;
    int pos,i;
    int m;
    char a[80];
    char b[80];
 
    init_str(&s, MAX_SIZE);
    printf("請輸入字符串1:\n");
    scanf("%s",a);
    printf("請輸入字符串2:\n");
    scanf("%s",b);
 
   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者這個准確些 
        ;
    create_str(&s, a, i);// 
    for(i = 0; b[i]; i++)//for(i=0;a[i]!='\0';i++) 后者這個准確些 
        ;
    
    create_str(&t, b, i);
    m = StrCompare(s,t); 
	printf("%d",m);                        
	
								 
    
    return 0;
}

串的簡單模式匹配BF算法

簡單的模式匹配算法是一種帶回溯的匹配算法,算法的基本思想這里不再進行描述,可以在網上或書上找到很好的答案。這個算法時間復雜度較高。

代碼實現

/*串的簡單模式匹配函數*/

#include<stdio.h>
 
#define MAX_SIZE 128
 
typedef struct
{
    char ch[MAX_SIZE];
    int last;//串的長度 
}string;
 
void init_str(string * s, int max)
{
    int i;
 
    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而誰的 ASCII 碼對應的是 整型的0呢?是字符'\0'
    s->last = 0;
}
 
void create_str(string * s, char * a, int n)
{
    int i=0; 
    for(;i < n; i++)
        s->ch[i] = a[i];
 
    s->ch[i+1] = '\0';
    s->last = n;
    printf("你輸入的字符串為:\n");
    printf("%s\n",s->ch);
}
 


//順序串的基本匹配算法

void StrIndex (string s,int pos,string t)
{
	/*求從主串的下標pos起....*/
	int i,j,start;
	if(t.last == 0)
		printf("匹配成功!");
	 start = pos;
	 i = start;//主串不一定從索引為0的字符開始,具體位置又客戶指定 
	 j = 0;//模式串從索引0開始 
	 while(i<s.last&&j<t.last)
	 {
	 	if(s.ch[i]==t.ch[j])
	 	{
	 		i++;
	 		j++;
	 	}
	 	else
	 	{
	 		start++;
	 		i = start;
	 		j=0;
	 	}
	 	
	 	
	 } 
	  if(j>=t.last)
	 	printf("匹配成功!匹配成功的位置索引為%d",start);
	  else
	 	printf("匹配失敗!"); 
	
}


 
int main()
{
    string s,t;
    int pos,i;
    int m;
    char a[80];
    char b[80];
 
    init_str(&s, MAX_SIZE);
    printf("請輸入字符串1:\n");
    scanf("%s",a);
    printf("請輸入字符串2:\n");
    scanf("%s",b);
 
   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者這個准確些 
        ;
   create_str(&s, a, i);// 
   for(i = 0; b[i]; i++)//for(i=0;bi]!='\0';i++) 后者這個准確些 
        ;
    
    create_str(&t, b, i);
                
	StrIndex (s,0,t);
								 
    
    return 0;
}

串的模式匹配改進的KMP算法

KMP算法的效率比Bf算法是要快的,具體的算法不再描述,這里只是簡單給出相關代碼實現。具體算法實現的內容可以參考課本和網上的解釋。

代碼實現

/*串的KMP匹配函數 */
/*http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html*/
/*上面的是對KMF算法的講解,我個人覺得寫的很清晰了emmmmm*/ 

#include<stdio.h>
 
#define MAX_SIZE 128
 
typedef struct
{
    char ch[MAX_SIZE];
    int last;//串的長度 
}string;
 
void init_str(string * s, int max)
{
    int i;
 
    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而誰的 ASCII 碼對應的是 整型的0呢?是字符'\0'
    s->last = 0;
}
 
void create_str(string * s, char * a, int n)
{
    int i=0; 
    for(;i < n; i++)
        s->ch[i] = a[i];
 
    s->ch[i+1] = '\0';
    s->last = n;
    printf("你輸入的字符串為:\n");
    printf("%s\n",s->ch);
}
 


//順序串的基KMP算法

void Index_KMP(string s,int pos,string t)
{
	int i,j;
	int next[MAX_SIZE];
	i = pos;
	j = 1;//規定若指向了空格的話就是0,所以這里從1開始 
	while(i<s.last&&j<t.last)
	{
		if(j == 0||s.ch[i] == t.ch[j])
		{
			i++;
			j++;
		}
		else
		{
			j = next[j];
		}
		 
	}
	if(j>=t.last)
	 	printf("匹配成功!匹配成功的位置索引為%d",i-j);//i是模式串移動后“最后”的位置索引, 
	else                                              //如果想要開始索引,減去“移動的塊的長度就可以了” 
	 	printf("匹配失敗!"); 

}


 
int main()
{
    string s,t;
    int pos,i;
    int m;
    char a[80];
    char b[80];
 
    init_str(&s, MAX_SIZE);
    printf("請輸入字符串1:\n");
    
    printf("請輸入字符串2:\n");
    scanf("%s",b);
 
   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者這個准確些 
        ;
   create_str(&s, a, i);// 
   for(i = 0; b[i]; i++)//for(i=0;bi]!='\0';i++) 后者這個准確些 
        ;
    
    create_str(&t, b, i);
                
	Index_KMP (s,0,t);
								 
    
    return 0;
}

參考文獻

  • 數據結構-用C語言描述(第二版)[耿國華]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM