JavaScriptで数値変換なしに文字列で表された数値同士を足し算する方法
JavaScriptでは、2つの数値を表す文字列 str1 と str2 を受け取り、それらの合計を求める関数を作成する必要があります。
ここでのポイントは、Number() や parseInt() を使って文字列全体を一括で数値に変換することなく、合計を計算し、その結果を文字列として返すことです。
この手法は、Number.MAX_SAFE_INTEGER を超えるような非常に大きな数値を扱う場合に特に有効です。通常の数値型では精度の問題が発生しますが、文字列のまま1桁ずつ計算すれば、どれほど大きな桁数でも正確な結果を得られます。
例
たとえば、次のような2つの文字列が与えられたとします。
const str1 = '234'; const str2 = '129';
この場合、期待される出力は「363」です。
アルゴリズムの考え方
基本的なアプローチは、私たちが普段行う筆算と同じ要領です。
- 両方の文字列の末尾(1の位)から順に1桁ずつ取り出す
- 取り出した桁同士と繰り上がり(carry)を加算する
- 合計が10以上なら繰り上がりを1として記録し、1の位だけを結果に連結する
- 両方の文字列を走査し終え、かつ繰り上がりがなくなるまでこの処理を繰り返す
コード例
以下が実際のコードです。
const str1 = '234';
const str2 = '129';
const addStringNumbers = (str1, str2) => {
let ind1 = str1.length - 1,
ind2 = str2.length - 1,
res = "",
carry = 0;
while(ind1 >= 0 || ind2 >= 0 || carry) {
const val1 = str1[ind1] || 0;
const val2 = str2[ind2] || 0;
let sum = +val1 + +val2 + carry;
carry = sum > 9 ? 1 : 0;
res = sum % 10 + res;
ind1--;
ind2--;
};
return res;
};
console.log(addStringNumbers(str1, str2));
コードの解説
- ind1 / ind2: 各文字列の末尾から先頭へ向かって走査するためのインデックスです。
- carry: 繰り上がりを保持する変数です。ある桁の合計が9を超えた場合に1となります。
- val1 / val2: インデックスが文字列の範囲外になった場合は
undefinedではなく0として扱われます(|| 0の部分)。このおかげで、桁数が異なる文字列同士の加算にも対応できます。 - +val1 + +val2: 単項プラス演算子(
+)を使い、取り出した1桁の文字だけを数値に変換しています。文字列全体の変換は一切行いません。 - sum % 10: 合計の1の位のみを取り出し、結果文字列の先頭に連結していきます。
出力
コンソールには以下のように出力されます。
363
-
JavaScriptで文字列内の空白を「%20」に変換する方法
Web上のURLにスペースが含まれている場合、ブラウザは自動的にすべての半角スペースを「%20」という文字列に置き換えます。本記事では、文字列を第一引数(唯一の引数)として受け取り、文字列中の空白があった位置をすべて「%20」に置き換えた新しい文字列を生成して返すJavaScript関数を作成します。問題の例たとえば、入力文字列が次の場合:const str = some extra Space;期待される出力は以下のとおりです。const output = some%20extra%20%20Space;「extra」と「Space」の間には元々2つ連続した空白があるため、出力では「%20%
-
JavaScriptで文字列内の文字を英字・数字・特殊文字に再グループ化する方法
問題文字列 str を第一引数(唯一の引数)として受け取る JavaScript 関数を作成する必要があります。この文字列には、次の3種類の文字が含まれる可能性があります。英字:(A-Z)、(a-z)数字:0〜9特殊文字:上記以外のすべての文字関数は文字列を先頭から順に走査し、ちょうど3つの要素からなる配列を構築します。1番目の要素には文字列に含まれるすべての英字、2番目には数字、3番目には特殊文字を格納し、それぞれ元の文字列内での出現順(相対的な順序)を維持します。最後にこの配列を返します。例えば、関数への入力が次の場合を考えてみましょう。入力const str = thi!1s is S@