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

JavaScriptで文字列内に最初に重複する文字のインデックスを求める方法

JavaScriptでは、文字列を引数として受け取り、その中で2回目以降に出現する(=重複している)最初の文字のインデックスを返す関数を作成できます。重複する文字がひとつも存在しない場合は、-1 を返す仕様とします。

例として、次のような文字列を考えてみましょう。

const str = 'Hello world, how are you';

この文字列の場合、最初に重複するのは「l」という文字です。「l」はインデックス 2 で初めて出現し、続くインデックス 3 でもう一度現れます。したがって、この関数は 2 を返す必要があります。

アルゴリズムの考え方

この問題を効率よく解くには、Map オブジェクトを使って「すでに登場した文字とそのインデックス」を記録しながら走査する方法が有効です。手順は以下の通りです。

  1. 空の Map を用意します。
  2. 文字列を先頭から1文字ずつ順番に調べます。
  3. 現在の文字が Map にすでに存在していれば、それが最初の重複文字なので、記録しておいたインデックスを即座に返します。
  4. 存在しない場合は、現在の文字とそのインデックスを Map に保存し、次の文字へ進みます。
  5. 最後まで走査しても重複が見つからなければ、-1 を返します。

コード例

const str = 'Hello world, how are you';

const firstRepeating = str => {
    const map = new Map();
    for(let i = 0; i < str.length; i++){
        if(map.has(str[i])){
            return map.get(str[i]);
        }
        map.set(str[i], i);
    }
    return -1;
};

console.log(firstRepeating(str));

実行結果

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

2

処理の流れの解説

このコードでは、まずインデックス 0 の「H」とインデックス 1 の「e」が初登場のため Map に登録されます。続いてインデックス 2 の「l」も Map に登録されますが、インデックス 3 に進むと再び「l」に遭遇します。この時点で map.has() が true を返すため、保存されていたインデックス 2 が即座に返され、処理は終了します。

計算量について

このアルゴリズムの時間計算量は O(n) です。文字列を一度だけ走査すればよいため、二重ループですべての文字ペアを比較する方法(O(n²))よりも大幅に高速で、長い文字列でも実用的なパフォーマンスを発揮します。また、Map の代わりに Set やプレーンなオブジェクトを使うことも可能ですが、Map を使うと「どの位置の文字が重複したのか」という情報も同時に保持できるため、今回のようなケースに特に適しています。

  1. JavaScriptで文字列内の特定文字の最大連続出現回数を求める方法

    本記事では、JavaScriptを使って「文字列の中である1文字が連続して出現する最大回数」を求める方法を解説します。アルゴリズムの考え方から実際のコード、実行結果まで、初心者にもわかりやすく説明していきます。 問題 次のようなJavaScript関数を作成することを目標とします。 第1引数として文字列を受け取る 第2引数として1文字を受け取る その文字が文字列内で連続して出現した最長の回数を数え、返す コード例 以下がその実装コードです。 {     const arr = str.split();     

  2. JavaScriptでアルファベットの1始まりのインデックスを取得する方法

    問題JavaScriptで関数を作成する必要があります。この関数は、小文字の英字アルファベット1文字を受け取り、その文字がアルファベットの中で何番目に位置するかを「1始まり」のインデックスとして返します。例えば、a なら 1、j なら 10 を返すといったイメージです。無効な入力が渡された場合は -1 を返してエラーを通知すると親切です。実装の考え方最もシンプルな方法は、先頭に半角スペースを付けたアルファベット文字列「 abcdefghijklmnopqrstuvwxyz」を基準(レジェンド)として用意することです。こうすることで、スペースが0番目となり、a は1番目、j は10番目というよう