4

C# を使用して、文字列内の繰り返し文字を見つけて置き換えることは可能ですか? jpeg 画像から変換された base64 文字列のサイズを縮小しようとしています。base64 文字列には、次のような多くの繰り返し文字が含まれていることに気付きました。

6qdQAUUxJA7uuCGQ8g/wA6fQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFYXiFL5b7TrmwtzM8Xmr7KWUAE+

このような方法で繰り返し文字を削除する方法があれば、全体的にはるかに小さくなります。

[QAUUUUAFFFFABRRR、18]

これは [REPEATED-CHARACTERS, NUMBER-OF-TIMES] の形式です。
これは可能でしょうか?助けてくれてありがとう。:)

4

3 に答える 3

1

基本的に、独自の可逆圧縮アルゴリズムを考え出そうとしています.zipのようなアルゴリズムは、文字列内の文字ではなくバイトで動作することを除いて、あなたが求めていることを正確に実行することで機能します.

一般的な圧縮アルゴリズムは、合理的な時間内に設計および実装できるものよりも効率的であることが事実上保証されています。1 つには、バイト アラインメントの問題により、base64 文字列では明らかではないパターンが見られる可能性があります。

では、 base64 でエンコードする にバイナリ データを圧縮するためにそれらの 1 つを使用するのではなく、その逆ではないのはなぜでしょうか?

于 2012-08-29T21:09:32.290 に答える
1

基本的に、検索と置換機能を作成する必要があります。それは、繰り返し文字列が一定の長さであるかどうかに大きく依存します。あなたの例では、反復文字列の長さは 16 文字であるため、最初の 16 文字を取得し、それらを次の 16 文字と比較するなど、異なる文字列が見つかるまでルーティングを記述することができます。次に、文字列を構文に置き換えて、それらを表します。

繰り返し文字列の長さが可変の場合は、もう少し複雑になります。基本的に、短い文字列から始めて、それを成長させ続け、同じ長さの次の文字セットと比較し、それらが繰り返される場合は、次の文字列をチェックする必要があります。ただし、これは失敗する可能性があります。

それらの多くは同様の原理で動作するため、圧縮アルゴリズムを検索してください。

于 2012-08-29T20:16:52.057 に答える
1

最大の繰り返しで最長の文字列を見つけることができます。

int mx = -1;
string str = null;
for (int i = 0; i < str.Length; i++) for (int j = i + 1; j < str.Length; j++)
{
string sub = str.Substring(i, j - i);
int tmp = countAll(str, sub); // write countAll() yourself
if (tmp > mx) { mx = tmp; str = sub; }
}

または、より良いのは、を使用することDictionaryです。

Dictionary<char, int> rep = new Dictionary<char, int>();
for (int i = 0; i < str.Length; i++)
  if (rep.ContainsKey(str[i])) rep[str[i]]++;
  else rep.Add(str[i], 1);

次に、各文字に出現回数を関連付けます。

string total = "";
foreach (var item in rep) total += item.Key;

追加:

本当に最長の繰り返し部分文字列を見つけたい場合は、代わりに動的計画法を使用してこの問題を解決する必要があります。

于 2012-08-29T20:52:37.913 に答える