1. 程式人生 > >資料結構之順序串的基本操作

資料結構之順序串的基本操作

            所謂的串就是字串,所謂順序串就是用陣列實現的字串,難道還有用連結串列實現的串嗎?真有,但我個人感覺那沒什麼用,在串這裡用連結串列可能反而會造成儲存空間的浪費,當然也有更好的利用連結串列實現串的方法。

               字串操作我想大家都比較熟悉了,如果你看過K&R的TCPL這本書你感覺到這些字串操作簡直就是...,真心推薦你看看這本書,好吧直接上原始碼。需要注意的是由於陣列是定長的,在進行一些連線等操作時需要注意截斷的出現和判斷處理。

str.h

/*---------------------------------------------------------------------------
	* file:str.h -->head file for SString.c
	* date:28-9-2014
	* author:
[email protected]
* version:1.0 * description:串的基本操作 --->使用定長順序實現 ------------------------------------------------------------------------------*/ #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 #define OK 1 #define ERROR 0 #define MAXSIZE 254 typedef unsigned char SString[MAXSIZE+1]; typedef int Status; /* * @description:產生一個字串 注意陣列的第一個元素為字串長度 */ Status StrAssign(SString *S,char *str); /* * @description:求串長 */ int StrLength(SString S); /* * @description:判空 */ Status StrEmpty(SString S); /* * @description:比較兩字串 */ Status StrCompare(SString S,SString T); /* * @description:由串S複製得串T */ Status StrCopy(SString S,SString *T); /* * @description:用T返回S1,S2連線的串 */ Status StrConcat(SString *T,SString S1,SString S2); /* * @description:用串Sub返回串S從第pos位置開始的長度為len的字串 */ Status SubString(SString *Sub,SString S,int pos,int len); /* * @description:判斷在串S在的pos的元素是否存在和串T相同的字元,如果存在則返回他的位置,否則返回0 */ int StrIndex(SString S,SString T,int pos); /* * @description:在串S的第pos個元素之前,插入串T */ Status StrInsert(SString *S,int pos,SString T); /* * @description:刪除第pos起長度為len的子串 */ Status DeleStr(SString *S,int pos,int len); /* * @description:替換S中所有與T相等不重疊的子串為V */ Status StrReplace(SString *S,SString T,SString V); /* * @description:清除串S */ void ClearStr(SString *S); /* * @description:銷燬串S */ void DestoryStr(SString *S); /* * @description:列印串 */ void StrPrint(SString S);

SString.c

/*---------------------------------------------------------------------------
	* file:SString.c
	* date:28-9-2014
	* author:[email protected]
	* version:1.0
	* description:串的基本操作 --->使用定長順序實現  
	* more:感覺最坑爹的是由於處理截斷的問題,讓程式變得十分麻煩
------------------------------------------------------------------------------*/


#include "str.h"



/*
* @description:產生一個字串 注意陣列的第一個元素為字串長度
*/
Status StrAssign(SString *S,char *str) {
	int i;
	/* 
	這裡進行清零是因為在後面的測試中發現了
	在整個陣列沒有賦值的地方出現了不可知
	的指,在進行比較是非常麻煩
	*/
	for(i = 0; i <= MAXSIZE;i++)
		(*S)[i] = '\0';
	for(i = 1; *str != '\0';i++,str++) {
		(*S)[i] = *str;
	}
	(*S)[0] = i - 1;

	return OK;
}

/*
* @description:求串長
*/
int StrLength(SString S) {
	return S[0];
}

/*
* @description:判空
*/
Status StrEmpty(SString S) {
	return S[0] == 0 ;
}


/*
* @description:比較兩字串
*/
Status StrCompare(SString S,SString T) {
	int i,j;
	i = j = 1;

	if(StrEmpty(S) || StrEmpty(T))
		return OVERFLOW;

	while(i <= S[0] && j <= T[0] && S[i] == T[j]) {
		i++;
		j++;
	}
	
	return S[i] - T[j];

}

/*
* @description:由串S複製得串T
*/
Status StrCopy(SString S,SString *T) {
	if(StrEmpty(S))
		return ERROR;

	int i;

	for(i = 1; i <= S[0]; i++)
		(*T)[i] = S[i];

	(*T)[0] = i;

	return OK;
}


/*
* @description:用T返回S1,S2連線的串
*/
Status StrConcat(SString *T,SString S1,SString S2) {
	if(StrEmpty(S1) || StrEmpty(S2))
		return ERROR;

	int i,j,len;

	len = 0;

	for(i = 1; i <= S1[0]; i++) {
		(*T)[i] = S1[i];
		len++;
	}
	
	for(j =1;j <= S2[0];j ++) {
		len ++;
		if(len == MAXSIZE)
			break;
		(*T)[len] = S2[j];
	}

	(*T)[0] = len;
	

	return OK;
}


/*
* @description:用串Sub返回串S從第pos位置開始的長度為len的字串
*/
Status SubString(SString *Sub,SString S,int pos,int len) {
	int i,j;

	if( pos < 1 || pos + len > S[0] || len < 0)
		return ERROR;

	for(i = pos,j = 1; i <= pos+ len; i++,j++)
		(*Sub)[j] = S[i];

	(*Sub)[0] = j - 1;

	return OK;
}


/*
* @description:判斷在串S在的pos的元素是否存在和串T相同的字元,如果存在則返回他的位置,否則返回0
*/

int StrIndex(SString S,SString T,int pos) {
	int i,n,m;
	SString Sub;
	
	for(i =0;i <= MAXSIZE;i++)
		Sub[i] = '\0';

	if(pos > 0) {
		i = pos;
		n = S[0];
		m = T[0];
	}
	//最多需要遍歷n-m+1次,有可能不需要這麼多次
	while(i <= n -m +1) {
		SubString(&Sub,S,i,m-1);

		if(!StrCompare(T,Sub)) 
			return i;
		else 
			i++;
	}

	return 0;
}


/*
* @description:在串S的第pos個元素之前,插入串T
*/
Status StrInsert(SString *S,int pos,SString T) {
	int i,n,m,j,k,tmp;

	n = (*S)[0];
	m = T[0];

	if(pos < 1 || pos > (*S)[0])
		return ERROR;

	if(n + m <= MAXSIZE)
		tmp = m + n;
	else
		tmp = MAXSIZE;
	
	(*S)[0] = tmp;

	for(i = tmp ; i > tmp - pos; i--)
		(*S)[i] = (*S)[i - m];
	for(j = pos,k = 1; j <= i && k <= m;j++,k++)
		(*S)[j] = T[k];



	return OK;
}


/*
* @description:刪除第pos起長度為len的子串
*/
Status DeleStr(SString *S,int pos,int len) {
	int i;

	if(pos < 1 || pos + len > (*S)[0] || len < 1)
		return ERROR;

	for(i = pos; i < pos + len; i++) 
		(*S)[i] = '\0';
	
	if(pos + len < (*S)[0])
		for(i = pos + len;i <= (*S)[0];i++)
			(*S)[i-len] = (*S)[i];

	(*S)[0] -= len;

	return OK;
}

/*
* @description:統計某子串在主串中出現的次數和位置(使用陣列)
*/
int IndexArr(SString S,SString T,int *arr) {
	int pos,index,i;

	pos = 1;
	i = 0;

	while(index = StrIndex(S,T,pos)) {
		arr[i++] = index;
		pos = index + T[0];
	}

	return i;
}


/*
* @description:替換S中所有與T相等不重疊的子串為V
*/
Status StrReplace(SString *S,SString T,SString V) {
	if(StrEmpty(*S) || StrEmpty(T) || StrEmpty(V))
		return ERROR;
	
	int n,m,l,num,k,j,len,tmp;
	SString R;
	int str[10];

	n =(*S)[0];
	m = T[0];
	l = V[0];
	num = IndexArr(*S,T,str);
	len = 1;
	tmp = 1;

	for(k = 0;k < num;k++) {
		for(; tmp < str[k];tmp++) {
			R[len++] = (*S)[tmp];

		}
		tmp =tmp +  m;
		for(j = 1; j <= V[0];j++)
			R[len++] = V[j];
	}

	if(tmp != 1) {
		for(;tmp <= n;tmp++)
			R[len++] = (*S)[tmp];
		for(j = 1; j < len;j++)
			(*S)[j] = R[j];
	}

	(*S)[0] = len -1;

	return OK;
}


/*
* @description:清除串S
*/
void ClearStr(SString *S) {
	(*S)[1] = '\0';
	(*S)[0] = 0;
}

/*
* @description:銷燬串S
*/
void DestoryStr(SString *S) {
	ClearStr(S);
}


/*
* @description:列印串
*/
void StrPrint(SString S) {
	int i;
	for(i = 1;i <=  S[0];i++)
		printf("%c",S[i]);
	printf("\n");
}

測試檔案test.c

/*---------------------------------------------------------------------------
	* file:test.c -->test file for SSting.c
	* date:28-9-2014
	* author:[email protected]
	* version:1.0
	* description:串的基本操作 --->使用定長順序實現
---------------------------------------------------------------------------*/



#include <stdio.h>
#include "str.h"

int main(int argc,char *argv[]) {
	char str[]="aabcefabch";
	char str1[]="abc";
	char str2[]="efg";
	int arr[10];

	SString S,T,V;
	int i,num;

	StrAssign(&S,str);
	StrAssign(&T,str1);
	StrAssign(&V,str2);
	printf("len:%d,empty:%d\n",StrLength(S),StrEmpty(S));
	StrReplace(&S,T,V);
	printf("\n");
	StrPrint(S);
	printf("len:%d,empty:%d,index:%d\n",StrLength(S),StrEmpty(S),StrIndex(V,T,2));

}

再附上用連結串列實現的串操作源:GitHub

相關推薦

資料結構順序基本操作——C語言

#include <stdio.h> #include <stdlib.h> #define MaxSize 100 typedef struct { char data[MaxSize]; int len; }SqString; voi

資料結構順序基本操作

            所謂的串就是字串,所謂順序串就是用陣列實現的字串,難道還有用連結串列實現的串嗎?真有,但我個人感覺那沒什麼用,在串這裡用連結串列可能反而會造成儲存空間的浪費,當然也有更好的利用連結串列實現串的方法。                字串操作我想大家

資料結構連結串列基本操作

涉及到單鏈表的基本操作有如下: int initList(linkList *);  //初始化一個單鏈表,具有頭指標,頭結點,頭結點->next=NULL; int createListHead(linkList *, int n);  //頭插法建立一個連

資料結構棧的基本操作

本文章包括了棧的建立,初始化,入棧,出棧,清除,銷燬,大小等 +棧的應用(進位制轉換) 棧的建立 typedef struct SqStack { ElemType *bottom;//棧底指標 ElemType *top;//棧頂指標 int stacksize;

資料結構佇列的基本操作

本文章包括了佇列的初始化,插入元素,刪除元素等 佇列結構體的建立 typedef struct { ElemType *base;//佇列儲存元素,也可用陣列代替 int front;//佇列頭部 int rear;//佇列尾部 }SqQueue; 佇列的初始化

資料結構順序佇列的操作(C語言)

#include <stdio.h> #include <stdlib.h> #include <string.h> #define QUEUELEN 15 //資料結構的定義 typedef struct { char name[

資料結構樹的基本操作(java版本)

本部落格來自慕課網《資料結構探險之樹篇》,慕課網主講老師使用C++實現的,這裡我將其改為java實現,以下是對程式碼的幾點說明:二叉樹:所有節點的度都小於等於2二叉樹的遍歷:根據訪問根的順序:前序、中序、後序。二叉樹陣列實現:左孩子下標 = 父節點下標2 + 1;右孩子下標

資料結構堆的基本操作

在實現堆的操作之前,先來明白什麼是堆? 堆中某個節點的值總是不大於或不小於其父節點的值 堆總是一棵完全二叉樹。 要說到完全二叉樹,直觀的判斷就是,層序遍歷一棵樹,如果樹的某個節點沒有右子樹或者是沒有子樹,那麼從這個節點後面的所有節點都不能夠有任何子樹。

資料結構連結串列基本操作總結

題意:  如何找到環的第一個節點? 分析:  1)先判斷是否存在環 使用兩個指標slow,fast。兩個指標都從表頭開始走,slow每次走一步,fast每次走兩步,如果fast遇到null,則說明沒有環,返回false;如果slow==fast,說明有環,並且此時fast超了s

資料結構與演算法:順序基本操作

#include "iostream"using namespace std;#define MaxSize 100typedef struct{char data[MaxSize];int length;}SqString;void Assign(SqString &

java 資料結構 順序儲存結構

package com.xdl.data_stru; /** * @author xudaolong 串的結構本質和char[]這種沒什麼區別; */ @SuppressWarnings("unused") public class Day_Four_SeqStrin

C 資料結構中單鏈表基本操作

C中的typedef C中的typedef關鍵字作用是為一種資料型別定義一個新名字,這樣做的目的有兩個,一是給變數定義一個易記且意義明確的新名字,如: typedef unsigned char BYTE; 把unsigned char型別自命名為BYTE。另一個目的是

資料結構:字串(堆)——基本操作

資料結構的重要行不言而喻,簡單介紹我在這部分遇到的一些問題,希望對大家有少許幫助。 首先實現的多個操作: 程式碼: #include<stdio.h> #include<stdlib.h> #include<string.h> #defi

c語言資料結構順序

c語言資料結構之順序表:     順序表的結構跟陣列比起來還是很像的,相比於連結串列,資料表的優勢主要體現在他的查詢速度上,而連結串列的優勢相反,查詢速度慢,但對於插入一個數據來說還是比較快的 下面我們就來建立一個順序表 1:定義資料型別,我定義的是一個學生的結構體型別,首

資料結構順序儲存結構線性表

順序儲存結構:元素按順序連續儲存。 一般它的定義儲存格式為: //定義資料格式 typedef struct { ElemType data[MAXSIZE]; //陣列儲存元素 int length; //線性表的長度 }Sq

資料結構順序表的操作函式

SeqList.h #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #include <stdio.h> #include <assert.h> #include <malloc.h> #include <window

資料結構順序

typedef struct { int *elem; int length; }Sqlist; int InitList(Sqlist &L){ L.elem=new int [100]; if(!L.elem) return 0; L.length=0;

資料結構順序表的實現(C語言)

實現程式碼: #ifndef __LINEARLIST_H__ #define __LINEARLIST_H__ #include <malloc.h> #include <stdi

資料結構-迴圈佇列的基本操作函式實現(含全部程式碼)

    主要包含以下函式:    InitQueue(SqQueue &Q)              引數:迴圈佇列Q 功能:初始化迴圈佇列Q 時間複雜度:O(1)     QueueEmpty(SqQueue Q)              引數:迴圈佇列Q

資料結構-鏈隊的基本操作函式的實現(含全部程式碼)

主要包含以下函式:        InitQueue(LinkQueue &Q) 引數:鏈隊Q 功能:初始化  時間複雜度O(1)     EnQueue(LinkQueue &Q,QElemType e) 引數:鏈隊Q,元素e 功能:將e入隊 時間複雜度