io non capisco a cosa serva, comunque la butto li ...
codice:
function getChars(&$str) {
	$arr = $output = array();
	$addChar = create_function('&$arr, $char', '
		$length = count($arr) - 1;
		if($length > -1 && $arr[$length]["char"] == $char)
			$arr[$length]["times"]++;
		else
			array_push($arr, array("char"=>$char, "times"=>1));
		return "";
	');
	preg_replace('/[^\a]/e', '$addChar($arr, "$0")', $str);
	for($i = 0, $length = count($arr); $i < $length; $i++)
		array_push($output, $arr[$i]["char"].'x'.$arr[$i]["times"]);
	return implode(' ', $output);
}

$str = 'aaaaaaaaaabbbaaaccccc'; 
echo getChars($str);

[edit]
se consideri che lettere multiple in testi normali non sono mai più di 2 e se consideri che questo tuo "compressore" per ogni doppione scrive 3 caratteri ($cxN) e se consideri che per ogni NON doppione invece di un carattere occupi di nuovo 3 ($cx1 invece di $c) ... vedi che invece di un compressore stai cercando di fare un "ingigantore" di stringhe ... i compressori sono altro