算法題0004-字符串壓縮

1.題目

給定一個字符串,對其進行壓縮。比如”aaaabbcddd”壓縮爲”a4b2c1d3″。若壓縮後的字符串沒有變短,則返回原來的字符串。

2.解法

解法1:利用StringBuffer

設定一個計數器,累計重複字符的個數,初始值爲1,ch爲第0(i=0)個字符。從i=1開始遍歷原字符串,若遍歷到的字符與ch相等,則cnt+1;否則,將ch、cnt添加至StringBuffer中,然後將cnt重置爲1,ch置爲當前i指向的字符,即ch=str.charAt(i)…

// 解法1
public String compressShorter(String str) {
	char ch = str.charAt(0);
	int cnt = 1;
	StringBuffer sb = new StringBuffer();
	for (int i = 1; i < str.length(); ++i) {
		if (ch == str.charAt(i)) {
			++cnt;
		} else {
			// 出現新字符str.charAt(i)
			// 把原字符ch和它的數量cnt追加至sb中
			sb.append(ch);
			sb.append(cnt);
			
			// 將ch置爲當前新字符,供下一次循環比較
			ch = str.charAt(i);
			// cnt重置爲1
			cnt = 1;
		}
	}
	/**
	 * 當重複字符改變時,纔會插入之前的字符。
	 * 因此還需要在末尾更新字符串。
	 * 因爲最後一組重複字符尚未放入壓縮字符串中
	 * 
	 */
	sb.append(ch);
	sb.append(cnt);
	
	// 比較壓縮字符串與原字符串的長度,根據題目要求返回其中一個字符串
	return sb.toString().length() < str.length() ? sb.toString() : str;
}

解法2:利用數組

不想或不能使用StringBuffer,可以根據壓縮後的字符串長度構建字符數組來處理。首先獲取壓縮後字符串的長度size,若沒有比原字符串短,則函數直接返回原字符串;否則,利用size創建一個char數組,遍歷原字符串,想方設法將字符和數量添加至char數組中。最後將數組轉爲字符串返回即可。

// 解法2:代碼較長,較複雜
public String compressShorter2(String str) {
	// 獲取壓縮後字符串長度
	int size = getNewLen(str);
	if (size >= str.length()) {
		// 不比原字符串短,直接返回
		return str;
	}
	char[] arr = new char[size];
	char ch = str.charAt(0);
	int cnt = 1;
	
	// index爲當前需要添加字符的arr下標,初始爲0。後面更新index,並添加字符
	int index = 0;
	for (int i = 1; i < str.length(); ++i) {
		if (ch == str.charAt(i)) {
			++cnt;
		} else {
			// 添加字符至arr,同時更新index
			index = setChar(arr, index, ch, cnt);
			ch = str.charAt(i);
			cnt = 1;
		}
	}
	setChar(arr, index, ch, cnt);
	return String.valueOf(arr);
}

// 設置字符,並更新index
public int setChar(char[] arr, int index, char ch, int cnt) {
	arr[index++] = ch;
	char[] charArray = String.valueOf(cnt).toCharArray();
	for (char c : charArray) {
		arr[index++] = c;
	}
	
	return index;
}

// 獲取壓縮後字符串的長度
public int getNewLen(String str) {
	if (str.length() == 0 || str == null) {
		return 0;
	}
	char ch = str.charAt(0);
	int size = 0;
	int cnt = 1;
	for (int i = 1; i < str.length(); ++i) {
		if (ch == str.charAt(i)) {
			// 重複字符,累計cnt
			++cnt;
		} else {
			
			// 數字轉爲字符串再加1(1表示一個字符的長度),累加到size中
			size += 1 + String.valueOf(cnt).length();
			ch = str.charAt(i);
			cnt = 1;
		}
	}
	size += 1 + String.valueOf(cnt).length();
	System.out.println("size: " + size);
	return size;
}

点赞