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

C++で文字列が「多様(ダイバース)」かどうかを判定する方法

問題の概要

小文字の英字からなる長さ n の文字列 S が与えられたとします。このとき、次の条件をすべて満たす文字列を「多様な文字列(diverse string)」と呼びます。

  • アルファベットが連続して並んでいること
  • それぞれの文字がちょうど1回だけ出現すること
  • なお、「a」と「z」は隣接しているものとはみなさない

この記事では、与えられた文字列 S が多様な文字列であるかどうかを C++ で判定する方法を解説します。

例えば、入力が S = "fced" の場合、文字を並べ替えると c, d, e, f となり、アルファベットが連続しているため、出力は True(1)になります。

解き方の手順

この問題は、以下の手順で解くことができます。

  1. 文字列 S を昇順にソートする
  2. フラグ変数 flag を 1 で初期化する
  3. i を 1 から開始し、i が S のサイズ未満かつ flag が 0 でない間、次の処理を繰り返す
     ・S[i] − S[i − 1] が 1 ではない場合、flag を 0 に設定する
  4. flag が 0 以外であれば true、そうでなければ false を返す

実装例

理解を深めるために、実際の C++ コードを見てみましょう。

#include <bits/stdc++.h>
using namespace std;
bool solve(string S){
    sort(S.begin(), S.end());
    int flag = 1;
    for (int i = 1; i < S.size() && flag; i++)
       if (S[i] - S[i - 1] != 1)
          flag = 0;
    return flag ? true : false;
}
int main(){
    string S = "fced";
    cout << solve(S) << endl;
}

入力

"fced"

出力

1

まとめ

このアルゴリズムのポイントは、まず文字列をソートすることです。多様な文字列であれば、ソート後は必ず「b, c, d…」のように隣接する文字同士の差が 1 になります。そのため、隣接する文字の差分を順番にチェックするだけで判定できます。

計算量は、ソート部分が O(n log n)、比較部分が O(n) となり、非常に効率的な手法です。文字列操作の基礎的な練習問題として、ぜひ参考にしてください。

  1. 【C++入門】バイナリ文字列の「1」の間に「0」が含まれているかを判定する方法

    今回は少し面白い文字列処理の問題を取り上げます。与えられたバイナリ文字列(0と1のみで構成された文字列)について、「1」の並びの中に「0」が挟まっていないかどうかを判定します。「0」が含まれていなければその文字列は有効(valid)、含まれていれば無効(invalid)とみなします。問題の例次の3つの文字列を見てみましょう。A:10001111010B:00001111100C:01111101111この中で有効なのは B の「00001111100」だけです。B は先頭から最初の「1」まで、そして最後の「1」以降には「0」がありますが、連続する「1」のブロック内部には「0」が一切存在しないた

  2. C++で文字列に部分文字列が含まれているか確認する方法|find()関数の使い方を解説

    ここでは、C++の標準文字列ライブラリ(std::string)を使って、メイン文字列の中に特定の部分文字列(サブストリング)が含まれているかどうかを確認する方法を解説します。検索には find() 関数を使用します。find() は、部分文字列が最初に出現する位置を返すため、この関数を繰り返し呼び出せば、メイン文字列内のすべての出現箇所を取得することができます。部分文字列が見つかった場合、find() はその位置(インデックス)を返します。一方、見つからなかった場合は特別な定数 string::npos を返します。したがって、「部分文字列がメイン文字列に存在するかどうか」を判定したい場合は