小螞蟻學習數據結構(16)——串的堆分配儲存代碼演示

    根據對書上僞代碼的理解,編寫了這麼一段堆分配儲存的程序,反正運行着沒有什麼問題,看看網上其餘人的代碼,具體細節上有所不一樣外,思路上都差很少。保存一下,萬一有高手過來,還能給指點一下。
函數

# include <stdio.h>
# include <stdlib.h>
# include <malloc.h>
# include <string.h>

//設置結構體變量
typedef struct string
{
	char * ch;
	int length;
}STRING,* PSTRING;

//函數前置聲明
//初始化結構體
void InitString( PSTRING );
//串的賦值操做
void StrAssign( PSTRING, char * );
//串的長度
int StrLength( PSTRING );
//比較兩個串的大小
int StrCompare( PSTRING, PSTRING );
//清空一個串
bool ClearString( PSTRING );
//拼接兩個串,組成一個新串
bool Concat( PSTRING, PSTRING, PSTRING );
//在某個位置上截取某個長度
bool SubString( PSTRING, PSTRING, int, int );

/*
	初始化
*/
void InitString(PSTRING str)
{
	str -> ch 		= NULL;
	str -> length 	= 0;
}

/*
	串的賦值操做
	@param	PSTRING	str	將目標串賦值到該串
	@param	char *	s   被複制的串
	return	void	
*/
void StrAssign(PSTRING str,char * s)
{
	int i, j;
	
	//判斷指針是否爲空,若是不爲空,將內存再用釋放
	if( str -> ch )
	{
		free( str -> ch );
		str -> ch = NULL;
	}
	
	//判斷傳入字符串的長度
	for( i = 0; s[i] != '\0'; i++ );
	
	//在內存中動態分配出空間
	str -> ch = ( char * )malloc( i * sizeof( char ) );
	if( NULL == str -> ch )
	{
		printf("動態內存分配失敗\n");
		return;
	}
	
	//逐個將值複製過來
	for( j = 0; j < i; ++j )
	{
		str -> ch[j] = s[j];
	}
	
	//給長度賦值
	str -> length = i;
	
	return; //結束
	
}

//返回串的長度
int StrLength( PSTRING str )
{
	return str -> length;
}

/*
	比較兩個串的大小
	@param	PSTRING	str1 其中一個串
	@param	PSTRING	str2 其中一個串
	return	int
	思路:
		1,逐個比較元素的ascii碼,返回正數或者負數
		2,若是比較完畢,在比較兩個串的長度,返回0 或者 非0
*/
int StrCompare( PSTRING str1, PSTRING str2 )
{
	int i;
	
	for( i = 0; i < str1->length && i < str2->length; ++i )
	{
		if( str1->ch[i] != str2->ch[i] )
		{
			return str1->ch[i] - str2->ch[i];
		}
	}
	
	return str1->length - str2->length;
}

//清空一個串
bool ClearString( PSTRING str )
{
	free( str -> ch );
	str -> ch = NULL;
	str -> length = 0;
	
	return true;
}

//拼接兩個串,組成一個新串
bool Concat( PSTRING str3, PSTRING str1, PSTRING str2 )
{
	int i, total;
	
	//釋放上一次使用的空間
	if( str3 -> ch )
	{
		/*
			free( str3 -> ch );
			這裏須要注意一下,以前這裏老報錯,檢查以後才知道,
			忘了爲str3初始化。不初始化的結果就是:str3 -> ch中
			保存的是一個垃圾值,而後到了下行要釋放空間的時候,由於
			保存的是一個垃圾值,或者是一個野指針,因此,程序出錯,
			初始化一下str3,就行了。
			PS:對初始化的認知更深入了。
		*/
		free( str3 -> ch );
		str3 -> ch = NULL;
		str3 -> length = 0;
	}
	
	//若是要拼接的兩個串是空串,返回false
	if( str1 -> length == 0  && str2 -> length == 0 )
	{
		return false;
	}
	
	//計算出兩個串的總長度
	total = str1->length + str2->length;
	//爲str3動態分配內存空間
	
	str3 -> ch = ( char * )malloc( total * sizeof( char ) );
	if( NULL == str3 -> ch )
	{
		printf( "動態內存分配失敗\n" );
		return false;
	}
		
	//將str1的內容複製到str3	
	for( i = 0; i < str1 -> length; ++i )
	{
		str3 -> ch[i] = str1 -> ch[i];
	}
	
	//將str2的內容複製到str3
	for( i = 0; i < str2 -> length; ++i )
	{
		str3 -> ch[str1->length + i] = str2 -> ch[i];
	}
	
	//把總長度賦值給str3
	str3 -> length = total;
	
	return true;
}

/*
	截取字符串
	@param	PSTRING	str	截取以後的新子串
	@param	PSTRING str1 將要截取的串
	@param	int		pos	 要截取的位置
	@param	int		len	 要截取的長度
	return boolean
*/
bool SubString( PSTRING str, PSTRING str1, int pos, int len )
{
	int i;
	/*
		首先對傳入參數進行驗證
		pos 的取值範圍 1 <= pos <= str1->length
		len 的取值範圍 0 <  len <= str1->length - pos + 1
	*/
	if( pos < 1 && pos > str1->length && len <= 0 && len > str1->length - pos + 1 )
	{
		return false;
	}
	
	//釋放上一次使用的空間
	if( str -> ch )
	{
		free( str -> ch );
		str -> ch = NULL;
		str -> length = 0;
	}
	
	//分配空間
	str -> ch = ( char * )malloc( len * sizeof(char) );
	if( NULL == str -> ch )
	{
		printf("動態內存分配失敗\n");
		return false;
	}
	
	//賦值操做
	for( i = 0; i < len; ++i )
	{
		str -> ch[i] = str1 -> ch[pos - 1 + i];
	}
	
	str -> length = len;
	
	return true;
}

//主函數
int main( void )
{
	int i;
	
	STRING str1, str2, str3, str4;
	InitString( &str1 );
	InitString( &str2 );
	InitString( &str3 );
	InitString( &str4 );
	
	printf( "將「abcde」賦值給str1\n" );
	printf( "將「fghijklmn」賦值給str2\n" );
	StrAssign( &str1, "abcde" );
	StrAssign( &str2, "fghijklmn" );
	
	i = StrCompare( &str1, &str2 );
	
	printf( "比較str1和str2的結果:%d\n", i );
	
	printf( "拼接str1和str2,而且賦值給str3:\n" );
	Concat( &str3, &str1, &str2 );
	for( i = 0; i < str3.length; ++i )
	{
		printf( "%c ", str3.ch[i] );
	}
	
	printf( "\n" );
	
	printf( "從str3的第5個元素截取5個值,賦予str4:\n" );
	SubString( &str4, &str3, 5, 5 );
	for( i = 0; i < str4.length; ++i )
	{
		printf( "%c ", str4.ch[i] );
	}
	
	printf( "\n" );
	
	printf( "清空str3串:\n" );
	if( ClearString( &str3 ) )
	{
		printf( "str3已經被清空\n" );
	}

	
	return 0;
}
/*
	在VC++6.0中輸出的結果是:
	===========================
	將「abcde」複製給str1
	將「fghijklmn」複製給str2
	比較str1和str2的結果:-5
	拼接str1和str2,而且賦值給str3:
	a b c d e f g h i j k l m n
	從str3的第5個元素截取5個值,賦予str4:
	e f g h i
	清空str3串:
	str3已經被清空
	===========================
*/

    就這麼着吧,有時間再把塊鏈的代碼實現一下,書上也真夠簡單的,僞代碼也給省略了……spa


    學PHP的小螞蟻 博客 http://my.oschina.net/woshixiaomayi/blog.net

相關文章
相關標籤/搜索