JavaScriptで文字列が同じパターンの繰り返しかどうかを判定する方法
はじめに
JavaScriptでは、文字列を引数として受け取り、その文字列が同じ文字パターンの繰り返しで構成されているかどうかを判定する関数を求められることがあります。
例えば、入力文字列が 'carcarcarcar' の場合、'car' というパターンが繰り返されているため、結果は true となります。一方、繰り返しパターンが見つからない場合は false を返します。
入力例
const str = 'carcarcarcar';
期待される出力
const output = true;
アルゴリズムの考え方
文字列が繰り返しパターンを持つかどうかを確認するには、以下の条件を利用します。
- 繰り返し単位の長さは、文字列全体の長さの半分以下である必要があります。
- 繰り返し単位の長さは、文字列の長さを割り切れる値でなければなりません。
- 各候補の長さ
jについて、すべての位置でstr[i] === str[i - j]が成り立つかを検証します。
コード例
以下が実際の実装コードです。
const str = 'carcarcarcar';
const isRepeating = (str = '') => {
if (!str.length) {
return false;
}
for (let j = 1; j <= str.length / 2; j++) {
if (str.length % j != 0) {
continue;
}
let flag = true;
for (let i = j; i < str.length; ++i) {
if (str[i] != str[i - j]) {
flag = false;
break;
}
}
if (flag) {
return true;
}
}
return false;
};
console.log(isRepeating(str));出力結果
コンソールには以下のように出力されます。
true
コードの解説
この関数は、まず空文字列の場合に false を返します。その後、長さ1から文字列長の半分までの各候補長 j について、文字列の長さが j で割り切れるかを確認します。割り切れない場合はスキップし、割り切れる場合はすべての文字が j 個前の文字と一致するかを検証します。すべて一致すれば true を返し、どの候補長でも一致しなければ false を返します。
別のアプローチ:正規表現を使う方法
より簡潔に書きたい場合は、正規表現を利用する方法もおすすめです。
const isRepeating = (str = '') => {
return /^(.+)\1+$/.test(str);
};
console.log(isRepeating('carcarcarcar')); // true
console.log(isRepeating('carcard')); // falseこの正規表現は、任意の1文字以上のパターン (.+) が1回以上繰り返されているかどうかを後方参照 \1 でチェックします。コード量が大幅に減り、可読性も向上します。
まとめ
文字列の繰り返し判定は、ループ処理による文字比較でも正規表現でも実装できます。パフォーマンスを重視する場合はループ処理、簡潔さを重視する場合は正規表現を選ぶとよいでしょう。
-
JavaScriptで文字列に含まれる母音の数を数えて返す方法
ここでは、アルファベットを含む可能性のある文字列を引数として受け取り、その文字列の中に存在する母音(a・e・i・o・u)の個数を数えて返すJavaScript関数の作成方法を解説します。実装のポイントは以下の通りです。大文字・小文字の違いを吸収するため、toLowerCase()で文字列をすべて小文字に変換します。母音の一覧「aeiou」を判定基準(legend)として用意します。文字列を1文字ずつループで走査し、母音リストに含まれる文字であればカウントを増やします。サンプルコード以下が実際のコード例です。 { str = str.toLowerCase(); &nb
-
マジックストリング(魔法の文字列)問題をJavaScriptで解く方法
マジックストリングの問題概要マジックストリング(魔法の文字列)とは、「1」と「2」だけから構成され、次の性質を持つ特別な文字列です。この文字列が「マジック(魔法)」と呼ばれるのは、連続する「1」や「2」のかたまり(グループ)ごとの出現回数をつなぎ合わせると、元の文字列そのものが再現されるからです。文字列 str の最初の部分は次のようになっています。str = 1221121221221121122……str 内の連続した「1」「2」をそれぞれグループに分けると、次のようになります。1 22 11 2 1 22 1 22 11 2 11 22 ……さらに、各グループにおける「1」または「2」の