JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

【JavaScript】配列で指定されたビット位置だけが1になる32ビット整数を返す関数の実装方法


問題

一意な非負整数からなる配列を受け取り、特定の32ビット整数を返すJavaScript関数を作成することを考えます。
戻り値となる整数は、2進数(バイナリ)表現にしたとき、右端から数えて配列に含まれる値と一致するビット位置だけが1になり、それ以外のビットはすべて0である必要があります。

たとえば入力が [1, 2, 0, 4] の場合、右から0番目・1番目・2番目・4番目のビットが1になるため、2進数では 10111 となります。これを10進数に変換すると 23 です。

コード例

以下が実装の一例です。

const arr = [1, 2, 0, 4];

const buildDecimal = (arr = []) => {
   // 32ビット分のビット状態を保持する配列(すべて0で初期化)
   const bitArr = Array(32).fill(0);
   let res = 0;

   // 配列の各要素に対応するビット位置を1に設定
   arr.forEach(el => {
      bitArr[31 - el] = 1;
   });

   // ビット配列をもとに10進数の値を組み立てる
   bitArr.forEach((bit, index) => {
      res += bit * Math.pow(2, 31 - index);
   });

   return res;
};

console.log(buildDecimal(arr));

出力

コンソールには次のように表示されます。

23

コードの解説

処理の流れ

最初に、32個の要素を持つ配列 bitArr を用意し、すべて0で初期化します。この配列は、32ビット整数の各ビットが0か1かを表しています。

次に、入力配列の各要素 el について、「右端から el 番目」の位置、すなわち配列のインデックス 31 - el を1に設定します。

最後に、ビットが立っている位置ごとに 2の(31 - index)乗 を計算して合計すれば、目的の10進数の値が求まります。

よりシンプルな実装

実は、ビット配列を明示的に用意しなくても、「各要素 el に対して 2 の el 乗を足し合わせる」という発想だけで同じ結果が得られます。

const buildDecimal = (arr = []) => {
   return arr.reduce((sum, el) => sum + Math.pow(2, el), 0);
};

さらに、ビット演算子を使えば次のようにも書けます。

const buildDecimal = (arr = []) => {
   return arr.reduce((res, el) => res | (1 << el), 0);
};

どちらの書き方でも結果は同じですが、reduce とビット演算を組み合わせた後者は簡潔で高速なため、実務ではこちらが好まれます。ただし、シフト演算は32ビット整数を前提としているため、安全に扱えるビット位置は 0〜30 程度までである点には注意してください。


  1. JavaScriptで配列を空にする方法まとめ【3つの手法と使い分けのポイント】

    JavaScriptで配列を空にする(初期化する)方法は複数あります。それぞれの手法には特徴や注意点があり、状況に応じて適切に使い分けることが重要です。この記事では、代表的な3つの方法と、それぞれのメリット・デメリットを詳しく解説します。まず、以下のような配列があると仮定します。let arr = [1, test, {}, 123.43];方法1:新しい空の配列で置き換えるarr = [];変数arrに新しい空の配列を再代入する方法です。最もシンプルかつ高速な手法として知られています。ただし注意点として、元の配列への参照がプログラムの他の場所に存在する場合、それらの参照は自動的に更新されませ

  2. JavaScriptの基本配列メソッド解説!push・pop・shift・unshift・spliceの使い方を実例付きで紹介

    JavaScriptには、配列を操作するための便利な組み込みメソッドが数多く用意されています。その中でも特によく使われるのが、要素の追加や削除を行う以下の5つの基本メソッドです。 JavaScriptの主要な配列メソッド一覧 メソッド説明 Array.push()配列の末尾に要素を追加します。 Array.pop()配列の末尾から要素を取り除きます。 Array.unshift()配列の先頭に要素を追加します。 Array.shift()配列の先頭から要素を取り除きます。 Array.splice()配列内の任意の位置で要素の追加・削除を行います。 これらのメソッドは、配列の