JavaScriptで2つの文字列を一致させるための削除文字ASCII値合計の最小化
問題
本記事では、英小文字のみで構成された2つの文字列 str1 と str2 をそれぞれ第1・第2引数として受け取るJavaScript関数の作成方法を解説します。
この関数の目的は、2つの文字列を完全に等しくするために削除しなければならない文字のASCII値の合計を求め、そのうち最小となる値を返すことです。
例として、関数への入力が以下の場合を考えてみましょう。
入力
const str1 = 'sea'; const str2 = 'eat';
出力
const output = 231;
出力の解説
まず、「sea」から「s」を削除すると、「s」のASCII値である 115 が合計に加算されます。
次に、「eat」から「t」を削除すると、116 が合計に加算されます。
この時点で両方の文字列は「ea」となり等しくなります。したがって、115 + 116 = 231 が、2つの文字列を一致させるために必要な削除文字のASCII値合計の最小値となります。
アプローチのポイント
この問題は動的計画法(DP)を用いることで効率的に解けます。各状態を「str1のある位置以降とstr2のある位置以降を一致させるのに必要な削除コストの最小値」と捉えます。対応する文字同士が一致する場合はコストなしで次の状態へ進み、一致しない場合はどちらか一方の文字を削除した場合のコストの小さい方を選択します。
境界条件として、片方の文字列の末尾に達した場合には、もう片方の残りの文字すべてのASCII値を合計した値が必要になります。この実装では二次元配列の代わりに1行分の配列をローリングさせて使うことで、メモリ使用量を抑えています。
コード例
以下が実際のコードです −
const str1 = 'sea';
const str2 = 'eat';
const minimumSum = (str1 = '', str2 = '') => {
const chartCode = (s = '') => {
let code = 0
for (const c of s) {
code += c.charCodeAt(0)
}
return code
}
let prev = new Array(str2.length + 1).fill(0)
for (let ind1 = str1.length; ind1 >= 0; ind1--) {
const current = new Array(str2.length + 1).fill(0)
for (let ind2 = str2.length; ind2 >= 0; ind2--) {
if (ind1 === str1.length) {
current[ind2] = chartCode(str2.slice(ind2))
} else if (ind2 === str2.length) {
current[ind2] = chartCode(str1.slice(ind1))
} else if (str1[ind1] === str2[ind2]) {
current[ind2] = prev[ind2 + 1]
} else {
current[ind2] = Math.min(
prev[ind2] + (str1[ind1]).charCodeAt(0),
current[ind2 + 1] + (str2[ind2]).charCodeAt(0),
)
}
}
prev = current
}
return prev[0]
}
console.log(minimumSum(str1, str2));
出力
231
-
JavaScript正規表現における\wと\Wの違いとは?
\w と \W の違い JavaScriptの正規表現において、\w と \W には重要な違いがあります。\w は「単語文字(ワードキャラクタ)」、つまり英数字やアンダースコアにマッチするのに対し、\W は「単語文字以外の文字(ノンワードキャラクタ)」、たとえば & や ^、% などの記号にマッチします。なお、\w は文字クラス [A-Za-z0-9_] と同等、\W はその否定である [^A-Za-z0-9_] と同等と考えると理解しやすいでしょう。以下で詳しく見ていきましょう。 構文1 new RegExp(\\w, g); 上記のコードは、JavaScriptで「単語文字」を検
-
JavaScriptのエスケープ文字とは?特殊文字のエスケープ方法と一覧を解説
エスケープ文字とは?エスケープ文字とは、プログラム上で本来意図した意味とは別の特別な意味に解釈されてしまう文字のことです。たとえば、ダブルクォートやシングルクォート、改行コードなどが該当します。こうした文字を「そのままの文字」として扱い、画面に出力したい場合には、直前にバックスラッシュ「\」を付けて記述します。この操作を「エスケープ処理」と呼びます。JavaScriptの主なエスケープ文字一覧コード意味・出力結果\bバックスペース\fフォームフィード\n改行(ニューライン)\rキャリッジリターン\t水平タブ\v垂直タブ\シングルクォート()\ダブルクォート()\\バックスラッシュ(\)バックス