JavaScriptで文字列を圧縮する方法|ランレングス圧縮の実装
本記事では、連続して繰り返される文字を含む可能性のある文字列を受け取り、それを圧縮して返すJavaScript関数の実装方法を解説します。
文字列圧縮のルール
この関数は、連続する同じ文字を「1文字+連続回数」の形式に変換することで、文字列を圧縮します。
'wwwaabbbb' -> 'w3a2b4' 'kkkkj' -> 'k4j'
圧縮しても短くならない場合の扱い
ただし、圧縮後の文字列の長さが元の文字列以上になってしまう場合は、圧縮を行わずに元の文字列をそのまま返す必要があります。
たとえば「aab」は「a2b1」と圧縮できますが、長さが3文字から4文字に増えてしまいます。このようなケースでは、関数は元の「aab」を返すように設計します。
サンプルコード
実際のコードは以下のとおりです。
const str1 = 'wwwaabbbb';
const str2 = 'kkkkj';
const str3 = 'aab';
const compressString = (str = '') => {
let res = '';
let count = 1;
for (let i = 0; i < str.length; i++) {
const cur = str[i];
const next = str[i + 1];
if (cur === next) {
count++;
} else {
res += cur + String(count);
count = 1;
}
}
return res.length < str.length ? res : str;
};
console.log(compressString(str1));
console.log(compressString(str2));
console.log(compressString(str3));
コードの解説
この実装は「ランレングス圧縮(Run-Length Encoding)」と呼ばれる古典的なデータ圧縮手法に基づいています。処理の流れは以下のとおりです。
- 文字列を先頭から順に走査し、現在の文字
curと次の文字nextを比較します。 - 両者が同じ場合はカウンター
countをインクリメントし、連続している回数を記録します。 - 異なる文字に切り替わったタイミングで「文字+連続回数」を結果文字列
resに追記し、カウンターを1に戻します。 - ループ終了後、圧縮結果の長さが元の文字列より短い場合のみ圧縮結果を返し、それ以外は元の文字列をそのまま返します。
実行結果
コンソールへの出力は次のようになります。
w3a2b4 k4j1 aab
1つ目の出力では「www」が「w3」、「aa」が「a2」、「bbbb」が「b4」に置き換えられています。一方、3つ目の「aab」は圧縮すると「a2b1」(4文字)となり、元の3文字より長くなるため、元の文字列がそのまま返されています。
-
JavaScriptで文字列を真偽値(Boolean)に変換する方法
JavaScriptでは、文字列が「true」というリテラルと一致するかどうかを比較演算子で判定することで、文字列を実質的に真偽値(Boolean)として扱うことができます。ここでは、==(緩い等価比較)と===(厳密等価比較)の2つの方法を使った具体例を紹介します。 サンプルコード <!DOCTYPE html> <html> <head> <style> body { font-family: &
-
JavaScriptで類似文字列のグループ数を求める方法
問題の概要2つの文字列 str1 と str2 は、str1 の異なる位置にある2つの文字を入れ替えることで str2 と一致させられる場合、「類似(similar)」していると定義されます。また、2つの文字列が完全に等しい場合も類似しているとみなします。例えば、tars と rats は類似しています(0番目と2番目の文字を入れ替えることで一致)。また rats と arts も類似しています。しかし star は tars、rats、arts のいずれとも類似していません。これらの文字列は、類似性によって次の2つの連結グループを形成します。{tars, rats, arts} と {sta