1. 程式人生 > >字串壓縮、解壓縮(時間優先)

字串壓縮、解壓縮(時間優先)

//字串壓縮、解壓縮 /* 時間優先 壓縮: 1、得到字串長度 利用長度申請一片新的記憶體newStr來儲存 2、遍歷源字串,如果不是'\0'進入迴圈 宣告 * pIndex 來記錄當前 字元 repetitionLength 記錄重複的字元次數 3、* pIndex 與 *(pIndex+1) 進行比較 如果相等 repetitionLength++ 返回執行3 4、判斷repetitionLength的值 ①如果==0 那麼不是相同的字元 *pNew++ = *p++; ②是存在相同字元 *pNew = repetitionLength + 1 + '0';//+ '0' 是為了將轉換為數字的char ; +1是因為本身也要計算在其中 *(pNew + 1) = *p;//儲存這個相同的字元,也就是5a 增量 回到 2 pNew = pNew + 2; p = p + repetitionLength + 1; 5、源字串走完 結束迴圈,重新申請記憶體,節約記憶體 strLength = strlen(newStr); newStr = _recalloc(newStr, strLength+1,sizeof(char)); 時間優先 解除壓縮: 跟上面差不多,就是得到指標判斷length

*/

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

//字串壓縮、解壓縮
/*
	時間優先 壓縮:
		1、得到字串長度 利用長度申請一片新的記憶體newStr來儲存
		2、遍歷源字串,如果不是'\0'進入迴圈
			宣告 
			* pIndex 來記錄當前 字元 
			repetitionLength 記錄重複的字元次數 
		3、* pIndex 與 *(pIndex+1) 進行比較 
			如果相等 
				repetitionLength++ 返回執行3
		4、判斷repetitionLength的值
				①如果==0
					那麼不是相同的字元 *pNew++  = *p++;
				②是存在相同字元
					*pNew = repetitionLength + 1 + '0';//+ '0' 是為了將轉換為數字的char ; +1是因為本身也要計算在其中
					*(pNew + 1) = *p;//儲存這個相同的字元,也就是5a
					增量 回到 2
					pNew = pNew + 2;
					p = p + repetitionLength + 1;
		5、源字串走完 結束迴圈,重新申請記憶體,節約記憶體
				 strLength = strlen(newStr);
				newStr = _recalloc(newStr, strLength+1,sizeof(char));
	時間優先 解除壓縮:
			跟上面差不多,就是得到指標判斷length 

*/

char * compress(char *str) {
	if (str == NULL)
		return NULL;

	//calloc()  會初始化為0
	//	引數一 :是大小
	//	引數二 :型別
	int strLength = strlen(str);
	char * newStr = calloc(strLength+1,sizeof(char));

	char *p = str;
	char *pNew = newStr;

	while (*p!='\0')
	{
		char *pIndex = p;
		int repetitionLength = 0;

		while (*pIndex == *(pIndex+1))//如果當前的字元和下一個字元相等
		{
			pIndex++;
			repetitionLength++;
		}

		if (repetitionLength==0)//不是相同的字元
		{
			*pNew++  = *p++;
		}else {//是相同的字元
			*pNew = repetitionLength + 1 + '0';//+ '0' 是為了將轉換為數字的char ; +1是因為本身也要計算在其中
			*(pNew + 1) = *p;//儲存這個相同的字元,也就是5a

			//*(pNew + 1) = repetitionLength + 1 + '0';//+ '0' 是為了將轉換為數字的char ; +1是因為本身也要計算在其中
			//*(pNew ) = *p;//儲存這個相同的字元,也就是a5

			pNew = pNew + 2;//前進字元
			p = p + repetitionLength + 1;
		}
	}

	//realloc函式用於修改一個原先已經分配的記憶體塊的大小。
	 strLength = strlen(newStr);
	 newStr = _recalloc(newStr, strLength+1,sizeof(char));


	return newStr;
}

char * decompress(char *str){
	if (str == NULL)
		return NULL;

	char * newStr = calloc(1000,sizeof(char));

	//雙指標
	char * p = str;
	char * pNew = newStr;


	while (*p!='\0')
	{
		char *pIndex = p;

		if (*pIndex >= '0'  &&  *pIndex <= '9')//當前字元是長度
		{
			int length = *pIndex - '0';
			for (size_t i = 0; i < length; i++)
			{
				*pNew ++= *(pIndex + 1);//因為是5a,+1就得後面的字元
			}
			p = p + 2;//前進字元
		}
		else { //不是數字 ,那麼就前進

			*(pNew++) = *(p++);//指標前進 並且將char賦值給newStr
		}

	}


	int strLength = strlen(newStr);
	newStr = _recalloc(newStr, strLength + 1, sizeof(char));

	return newStr;

}

void main() {
	char rStr[] = "aaaaabbbbccc";

	printf("源字串 -> %s \n", rStr);

	printf("壓縮後字串 -> %s \n", compress(rStr));
	
	printf("解除壓縮後字串 -> %s \n", decompress(rStr));

	system("pause");
}