JavaScriptで2進数のビットに合わせて文字列の大文字と小文字を入れ替える方法
問題
文字列 str と数値 n を引数に受け取り、n を使って文字列を変換する JavaScript 関数を作成します。
数値 n の各ビットは、文字列中の英字ごとの処理を決定します。
- ビットが 1 の場合 … 対応する英字の大文字と小文字を入れ替える
- ビットが 0 の場合 … 元の文字のまま変更しない
n の最後のビットまで使い切ったら、再び先頭のビットに戻って同じ処理を繰り返します。最終的に、変換後の新しい文字列を返却してください。
コード例
const str = 'hey there';
const num = 21;
const swapCase = (str = '', num = 1) => {
// 英字の文字数をカウント
const alphaLength = str
.split('')
.reduce((acc, val) => val.toLowerCase() !== val.toUpperCase() ? ++acc : acc, 0);
// 数値を2進数表現の文字列に変換
let binary = num.toString(2);
// 2進数の長さが英字の文字数に満たない場合は、自身を繰り返して拡張
while (binary.length < alphaLength) {
binary += binary;
}
let res = '';
for (let i = 0; i < str.length; i++) {
const el = str[i];
const isAlpha = el.toUpperCase() !== el.toLowerCase();
// 英字かつ対応するビットが1の場合のみ、大文字と小文字を入れ替える
if (isAlpha && +binary[i] === 1) {
res += el.toLowerCase() === el ? el.toUpperCase() : el.toLowerCase();
} else {
res += el;
}
}
return res;
};
console.log(swapCase(str, num));
処理の流れ
split('')とreduce()を組み合わせて、文字列に含まれる英字の総数(alphaLength)を求めます。大文字変換と小文字変換の結果が一致しない文字=英字、という性質を利用しています。num.toString(2)で数値を2進数表現の文字列に変換します(例:21 → "10101")。- 2進数の長さが英字の総数に満たない場合は、自身を連結して必要な長さまで伸ばします。これにより、すべての英字に必ず対応するビットが割り当てられます。
- 文字列を先頭から1文字ずつ走査し、「その文字が英字」かつ「対応するビットが 1」である場合にだけ、大文字と小文字を入れ替えて出力用の文字列に追加します。
- 数字や記号など英字以外の文字は、ビットの値にかかわらず常にそのままコピーされます。
実行結果
上記のコードを str = 'hey there'、num = 21 で実行すると、コンソールには次のように出力されます。
HeY THeRe
動作の検証
21 を2進数で表すと "10101" です。入力文字列には英字が8文字含まれているため、このパターンを繰り返した "1010110101" が各文字に対応します。
| 位置 | 文字 | ビット | 結果 |
|---|---|---|---|
| 0 | h | 1 | H(入れ替え) |
| 1 | e | 0 | e(そのまま) |
| 2 | y | 1 | Y(入れ替え) |
| 3 | (空白) | ― | (そのまま) |
| 4 | t | 1 | T(入れ替え) |
| 5 | h | 1 | H(入れ替え) |
| 6 | e | 0 | e(そのまま) |
| 7 | r | 1 | R(入れ替え) |
| 8 | e | 0 | e(そのまま) |
このように、ビットが 1 の位置の英字だけが入れ替わり、それ以外の文字は元のまま残るため、結果は "HeY THeRe" となります。
補足:より簡潔な2進数の拡張方法
repeat() を使えば、while ループによる拡張処理を1行で書き換えることもできます。
let binary = num.toString(2) .repeat(Math.ceil(alphaLength / num.toString(2).length));
-
JavaScriptで文字列数値の後半の桁を0に変換する方法
問題文字列形式の数値を唯一の引数として受け取るJavaScript関数を作成する必要があります。この関数は、入力された数値の後半の桁をすべて「0」に置き換えた結果を返すものとします。桁数が奇数の場合は、中央の桁から後ろをすべて0に変更します。例えば、以下のように変換されます。938473 → 938000コード例以下が実装コードです。const num = 938473;const convertHalf = (num = ) => { let i = num.toString(); let j
-
JavaScriptでバイナリ文字列を単調増加にするための最小反転回数を求める方法
単調増加文字列とは0と1のみで構成される文字列が「単調増加」とみなされるのは、任意の個数(0個でも可)の0が先頭に並び、その後に任意の個数(これも0個でも可)の1が続く場合です。つまり、「000111」「0011」「1」などは単調増加ですが、「1100」「010」などは該当しません。問題の概要本記事では、バイナリ文字列 str を唯一の引数として受け取るJavaScript関数を作成します。文字列内の任意の0を1へ、または任意の1を0へと反転(フリップ)することができます。このとき、文字列全体を単調増加にするために必要な最小の反転回数を求めて返すのが目標です。入力例const str = 00